main

리액트 딥다이브 살펴보기 IV

Log
4

오늘은 2장의 1,2 섹션을 읽고 느낀점과 탐구하고자 했던 것을 포스팅하고자 합니다.

📌 JSXElement는 createElement의 문법적 설탕?

이전에 리액트를 공부하면서 JSXElementcreateElement의 문법적 설탕이다. 라는 이야기를 들어본적이 있습니다.
jsx 문법을 사용해서 리턴문을 쓰면 결국 바벨이 돌아갈 때, createElement를 통해서 ReactNode로 다시 트랜스파일링 된다는 것이었는데요.

리액트 딥다이브에서는 아래와 같은 예시가 책에 나와있습니다.

import React from 'react';
import { PropsWithChildren, createElement} from 'react';
 
function TextOrHeading({
  isHeading,
  children
}: PropsWithChildren<{isHeading: boolean}>) {
  return isHeading ? (
    <h1 className="text">{children}</h1>
  ) : (
    <span className="text">{children}</span>
  )
}
 
function TextOrHeading2({
  isHeading,
  children
}: PropsWithChildren<{isHeading: boolean}>){
  return createElement(
    isHeading ? 'h1' : 'span',
    { className: 'text'},
    children,
    )
}

TextOrHeading2가 바벨로 트랜스파일링된다면 아래와 같습니다.

function TextOrHeading2({
  isHeading,
  children
}) {
  return createElement(isHeading ? 'h1' : 'span', {
    className: 'text'
  }, children);
}

따라서 createElement를 사용한다면 바벨로 트랜스파일링 되어도 타입이 제거되는 것 이외에는 별다른 차이가 없는 것을 알 수 있습니다. 따라서, 트랜스파일링의 비용도 적어질 수 밖에 없을 것 같은.. 그런 저의 추측을 해봅니다.🧐 (따라서 필요에 따라 createElement를 사용하는 것이 효율적이다..)
jsx는 결국 createElement를 사용해서 트랜스파일링 되는데, 내부 구조 순서는 아래와 같이 적어줄 수 있습니다.
JSXchildren > JSXattributes > JSXstring 순서대로 적어주면 됩니다.
예제를 통해서 PropsWithChildren타입에 제네릭을 넣어줄 수 있다는 걸 처음 알게 되었습니다.

type PropsWithChildren<P = unknown> = P & { children?: ReactNode | undefined };

제네릭으로 P타입을 넣어주면 P타입과 함께 children타입이 같이 타입이 명시되는 것을 알 수 있었습니다.
또한 저는 index.d.ts에서 ReactFragment타입을 열심히 찾아 다녔었는데요.
ReactNode타입을 확인하고, ReactFragment타입에 대한 명시도 바뀌게 되었다는 것을 알게 되었습니다.
이전에는 ReactFragment로 명시하였었는데, 아래와 같이 변경되었습니다.

    type ReactNode =
        | ReactElement
        | string
        | number
        | Iterable<ReactNode>  // ReactFragment
        ...

위와 같이 ReactFragmentIterable<ReactNode>로 타입이 기입되고 있다는 것을 알게 되었습니다.
아래는 실제 index.d.ts에서 정의된 ReactFragment타입입니다.

type ReactFragment = Iterable<ReactNode>;
  • 결론
    • 결론적으로, JSX문법만 사용하기 보다는 createElement를 사용하면 효율적일 수 있다를 알 수 있었습니다.

김다은 이모지
Daeun Kim
Junior Frontend Engineer