Closed hyeyoonS closed 2 months ago
React.ReactElement, JSX.Element, React.ReactNode는 모두 리액트 요소를 나타내는 타입입니다. 다만 각 타입은 아래처럼 약간의 차이를 보입니다.
React.ReactElement
JSX.Element
React.ReactNode
이런 차이로 인해 각 타입이 주로 활용되는 상황이 다음과 같습니다.
React.ReactNode
JSX.Element
React.ReactElement
우선 JSX에 대해서 살펴볼 필요가 있습니다.
⇒ 즉, JSX는 리액트 엘리먼트를 생성하기 위한 문법이며 트랜스파일러는 JSX 문법을 createElement 메서드 호출문으로 변환하여 리액트 엘리먼트를 생성합니다.
⇒ JSX 코드를 작성하면 해당 코드는 JSX.Element로 변환되고, 이는 React 애플리케이션에서 React.ReactElement로 변환됩니다. React.ReactNode은 React 애플리케이션에서 렌더링 가능한 모든 요소를 포함하는 범용적인 개념이며, JSX.Element는 TypeScript에서 JSX 요소의 타입을 정의하기 위해 사용됩니다.
interface IconProps {
size: number;
}
interface Props {
// Item 컴포넌트의 props를 정의.
// ReactElement의 props 타입으로 IconProps 타입 지정
icon: React.ReactElement<IconProps>; // icon의 props의 타입은 IconProps
// icon은 IconProps 타입의 props를 갖는 ReactElement임을 명시.
}
const Item = ({ icon }: Props) => {
//icon을 props로 받음
// icon prop으로 받은 컴포넌트의 props에 접근하면, props의 목록이 추론된다
const iconSize = icon.props.size; // icon의 props에 접근.
return <li>{icon}</li>;
};
⇒ 타입스크립트가 JSX를 사용할 때 정의하는 타입입니다.
// JSX.Element 타입을 사용하여 React 컴포넌트에서 자식 컴포넌트를 props로 전달하고,
// 그 자식 컴포넌트의 props에 접근하는 방법
//IconProps을 JSX.Element 타입으로 선언함으로써 해당 prop에는 JSX 문법만 삽입할 수 있다.
interface IconProps {
icon: JSX.Element;
}
const Item = ({ icon }: IconProps) => {
// icon을 prop으로 받음.
// prop으로 받은 컴포넌트의 Iconprops에 접근할 수 있다
const iconSize = icon.Iconprops.size; // icon의 props에 접근하여 size 속성을 가져옴.
// icon이 JSX 요소이기 때문에 가능함.
return <li>{icon}</li>;
};
// icon prop에는 JSX.Element 타입을 가진 요소만 할당할 수 있다
const App = () => {
return <Item icon={<Icon size={14} />} />; // Icon컴포넌트는 JSX.Element 타입의 요소
};
JSX를 사용하여 작성된 모든 구조 요소를 말합니다. ⇒ React 컴포넌트의 렌더링 결과물로 나오는 모든 종류의 Node를 나타내는 타입 입니다. ⇒ 문자열, 숫자, 또는 ReactElement와 같은 JSX Element 등 다양한 종류의 값을 포함합니다.
JSX형태의 문법을 어떤 타입이든 children prop으로 지정할 수 있게 하고 싶다면, ReactNode 타입으로 children을 선언하면 된됩니다.
type ReactFragment = {} | Iterable<ReactNode>; // ReactNode의 배열 형태
type ReactNode =
| ReactChild
| ReactFragment
| ReactPortal
| boolean
| null
| undefined;
interface ReactElement<
P = any,
T extends string | JSXElementConstructor<any> =
| string
| JSXElementConstructor<any>
> {
type: T;
props: P;
key: Key | null;
}
예시
const element = React.createElement('div', { className: 'container' }, 'Hello, World!');
// 또는
const element = <div className="container">Hello, World!</div>;
type ReactNode =
| ReactElement
| string
| number
| ReactFragment
| ReactPortal
| boolean
| null
| undefined;
declare global {
namespace JSX {
interface Element extends React.ReactElement<any, any> { }
}
}
❓문제
🎯답변
ReactElement
예시
ReactNode
JSX.Element