ReactNode vs ReactElement(JSX.Element)의 차이

이수빈·2023년 3월 5일
0

React

목록 보기
2/17
  • 프로젝트 리팩토링을 진행하던 도중 다음과 같은 오류가 발생했다.
  • Spinner 컴포넌트를 컴포넌트 형태로 넘겨주지 않아서 발생한 어이없는 Error였지만, 덕분에 ReactNode와, React Element, JSX Element에 대해 알게되어서 글을 작성하게 되었다.

ReactNode란?

  • typescript react index.d.ts 파일에서 ReactNode의 type을 가져왔다.

  • ReactElement외에도 여러가지를 포괄하는 type이다.

  • 클래스형 컴포넌트는 render메소드에서 ReactNode를 return한다.


type ReactFragment = Iterable<ReactNode>; // ReactNode의 이터러블 형태

interface ReactPortal extends ReactElement {
        key: Key | null;
        children: ReactNode;
} // Portal은  key값을 가진 ReactNode

type ReactNode = 
ReactElement| string | number |
ReactFragment | ReactPortal | boolean | null | undefined;

ReactElement란?

  • React.createElement 함수를 사용하면 ReactElement Type이 return된다.

  • ReactElement는 type과 prop을 갖는데, type으로는 JSX Element나 string이 올 수 있다.


type JSXElementConstructor<P> =
        | ((props: P) => ReactElement<any, any> | null)
        | (new (props: P) => Component<any, any>);


interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
    }
  • React에서 JSX를 사용하면, 바벨이 이를 React Element의 형태로 트랜스파일링 해준다.

  • 트랜스파일은 컴파일과 많이 비교된다.

  • 컴파일은 한 언어로 작성된 소스코드를 다른 언어로 변환시키는 것,

  • 트랜스파일은 한 언어로 작성된 소스 코드를 비슷한 수준의 추상화를 가진 다른 언어로 변환하는 것이다.

  • 그렇기때문에, JSX를 사용하는 함수형 컴포넌트에서는 ReactElement type이 return 되는 것이다.

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
); // 트랜스파일이전

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
); // 트랜스파일 이후

JSX.Element란?

  • JSX.Element는 JSX라는 namespace에 정의되어 있다.

  • JSX.Element는 ReactElement를 제너릭으로 확장한것이다. type, prop이 any type을 갖는다.

  • namespace란? 인터페이스, 클래스, 함수 등을 묶는 단위로, 모듈과 비슷한 역할을 한다.

  • 모듈이 없었을때는, 네임스페이스를 통해 모듈을 관리하고 재사용했다. 타입스크립트 공식문서에도 현재는 모듈사용을 권장한다.

declare global {
    namespace JSX {
        interface Element extends React.ReactElement<any, any> { }
        interface ElementClass extends React.Component<any> {
            render(): React.ReactNode;
        }

ref)
types/react/index.d.ts(React 18.0 version 기준) - https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts

트랜스파일,컴파일 : https://inpa.tistory.com/entry/CS-%F0%9F%96%A5%EF%B8%8F-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8C%8C%EC%9D%BC-%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0-%EB%B9%84%EA%B5%90-%EC%89%BD%EA%B2%8C-%EC%84%A4%EB%AA%85

네임스페이스,모듈 : https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html

profile
응애 나 애기 개발자

0개의 댓글