ReactNode와 ReactElement의 차이

김세빈·2025년 5월 9일

프론트엔드

목록 보기
3/3

타입의 범위

세 가지 타입은 아래와 같이 포괄 관계를 가진다:

ReactNode > ReactElement ≒ JSX.Element
  • ReactNode: 가장 포괄적인 타입. 문자열, 숫자, boolean, null, undefined, ReactElement, ReactFragment, ReactPortal 등 모두 포함된다.
  • ReactElement: 컴포넌트의 반환값으로 가장 많이 사용되는 타입. JSX의 결과물이기도 하다.
  • JSX.Element: ReactElement<any, any>의 타입 alias로 거의 같은 개념이다.

ReactElement란?

ReactElement는 컴포넌트가 반환하는 객체의 형태를 타입으로 정의한 것이다.

interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
  type: T;
  props: P;
  key: Key | null;
}

즉, JSX 문법을 사용하면 내부적으로 React.createElement() 함수가 호출되어 ReactElement 객체를 생성한다.

예를 들어 다음 JSX 코드를:

<CustomButton disabled>버튼</CustomButton>

바벨은 아래처럼 트랜스파일링 한다:

React.createElement(CustomButton, { disabled: true }, "버튼")

JSX.Element란?

JSX.Element는 전역 JSX 네임스페이스에 정의되어 있으며, React.ReactElement<any, any>와 같다.

declare global {
  namespace JSX {
    interface Element extends React.ReactElement<any, any> {}
  }
}

따라서 함수형 컴포넌트에서 반환하는 타입으로 JSX.Element 또는 ReactElement를 사용할 수 있다. 사실상 이 둘은 동일하다고 봐도 무방하다.

function MyComponent(): JSX.Element {
  return <div>Hello</div>;
}

ReactNode란?

ReactNode는 JSX에서 표현할 수 있는 모든 값을 포함하는 타입이다. 대표적으로 다음과 같은 타입들이 포함된다:

  • string, number
  • boolean (렌더링되지 않음)
  • null, undefined
  • ReactElement
  • ReactFragment (여러 요소를 묶는 용도)
  • ReactPortal (DOM 외부로 렌더링)

예를 들어 children 타입에 가장 흔하게 사용되는 타입이다:

type PropsWithChildren<P> = P & { children?: ReactNode };
function Layout({ children }: { children: ReactNode }) {
  return <div>{children}</div>;
}

언제 어떤 타입을 써야 할까?

상황타입 추천이유
함수형 컴포넌트 반환값ReactElement or JSX.Element대부분 JSX를 반환하므로
children propReactNode텍스트, 태그, 배열 등 모든 표현 가능
UI를 동적으로 조립할 때ReactNode배열, 조건부 렌더링 등을 지원해야 함
특정 엘리먼트를 명확히 감쌀 때ReactElementReact.cloneElement() 등과 같이 엘리먼트 자체를 다룰 때

0개의 댓글