프로젝트 태스크를 진행하다가 children 타입을 React.ReactElement; 로 두고 태스크 완성한 걸 PR에 올려두었다.
여기서 받은 다른 팀원 분의 질문
요기 ReactNode가 아니라 ReactElement로 타입 좁혀놓으신 이유가 있을까용?
이 질문을 보면서 ReactNode와 ReactElement의 차이를 제대로 설명을 할 수 있어야겠다고 생각하여 공부하면서 이 포스트에 정리해보겠다.
children의 타입으로 사용하는 타입에는 크게 ReactNode와 ReactElement가 있다.
ReactNode
-> 클래스형 컴포넌트의 리턴값에 해당
ReactNode는 JSX에서 children으로 전달될 수 있는 모든 타입을 가질 수 있다.
string, number, boolean, null, undefined, ReactElement, ReactFragment, ReactPortal
interface ModalRendererProps {
title: string;
children: React.ReactNode;
}
보통 children을 유연하게, 범용적으로 사용하기 위해 ReactNode를 많이 쓴다.
ReactElement
-> 함수형 컴포넌트의 리턴값에 해당
ReactElement는 오직 JSX 요소만을 가질 수 있다. 즉, 자바스크립트의 원시 타입들은 가질 수 없다는 것!
type, props를 가진다.
interface ModalRendererProps {
title: string;
children: React.ReactElement;
}
interface ReactElement<
P = any,
T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>,
> {
type: T;
props: P;
key: string | null;
}
ReactElement는 createElement 함수를 통해 생성된 객체의 타입이다.
따라서 ReactElement 타입은 자식 요소로 하나의 컴포넌트를 받는 것을 강제해야 하는 상황에 사용할 수 있다!
그렇다면 여기서 추가적으로 JSX.Element는 JSX 요소만을 가지는 ReactElement와 무슨 차이가 있을까?
JSX.Element
JSX.Element는 ReactElement의 타입과 props를 모두 any로 받는다. ReactElement의 특정 타입이라고 생각하면 된다.
declare global {
namespace JSX {
interface Element extends React.ReactElement<any, any> {}
}
}
ReactNode > ReactChild > ReactElement
'React' 카테고리의 다른 글
[React / Recoil] Link 태그와 a 태그의 차이(userState가 undefined가 생기는 문제) (0) | 2023.06.19 |
---|