// JSX 코드를 @babel/plugin-transform-react-jsx로 변환한 결과
'use strict'
var ComponentA = React.createElement(
A,
{
required: true
},
'Hi',
)
var ComponentB = React.createElement(React.Fragment, null, 'Hi')
var ComponentC = React.createElement(
'div',
null,
React.createElement('span', null, 'Hi'),
)
리액트 17, 바벨 7.9.0 이후 버전에서 추가된 자동 런타임(automatic runtime)으로 트랜스파일한 결과는 조금 다르지만 결국에는 공통점이 있습니다.
1. JSXElement를 첫 번째 인수로 선언해 요소를 정의합니다.
2. 옵셔널인 JSXchildren, JSXAttributes, JSXStrings는 이후 인수로 넘겨주어 처리합니다.
이를 통해서 실제 활용해 볼 수 있는 점은 JSXElement를 렌더링해야 할 떄, 굳이 요소 전체를 감싸지 않더라도 처리할 수 있다는 점입니다. 이는 JSXElement만 다르고, JSXAttributes, JSXChildren이 완전히 동일한 상황에서 중복 코드를 최소화 할 수 있어 유용합니다.
// props 여부에 따라 children 요소만 달라지는 경우
// 굳이 번거롭게 전체 내용을 삼항 연산자로 처리할 필요가 없다.
// 이 경우 불필요한 코드 중복이 일어난다.
import {createElement, PropsWithChildren} from 'react'
function TextOrHeading({
isHeading,
children,
}: PropsWithChildren) {
return isHeading ? (
<h1 className="text">{children}</h1>
) : (
<span>{children}</span>
)
}
// JSX가 변환되는 특성을 활용한다면 다음과 같이 간결하게 처리 할 수 있다.
import {createElement} from 'react'
function TextOrHeading({
isHeading,
children
}: PropsWithChildren<{ isHeading: boolean}>) {
return createElement(
isHeading ? 'h1' : 'span',
{ className: 'text' },
children,
)
}
JSX 반환값이 결국 React.createElement로 귀결된다는 사실을 파악한다면 이런 식으로 쉽게 리팩토링 할 수 있습니다.