목차
에러 분석
리액트 컴포넌트를 사용할 때에는 무조건 대문자로 시작해야 한다. <bCompo>
라는 소문자 컴포넌트를 이용을 하면 브라우저에 이런 에러가 뜬다.
에러
The tag<bCompo>
is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.
해석
<bCompo>
는 이 브라우저에서 인식되지 않습니다. React 구성 요소를 렌더링하려는 경우 이름을 대문자로 시작하세요.
리액트에서도 친절하게 대문자를 사용하라고 한다. 왜 대문자로 사용해야 할까? 그것을 알려면 리액트 JSX문법의 원리를 알아야 한다.
React.createElement()
리액트 공식문서에서 createElement를 살펴볼수 있다. 우리가 흔히 사용하는 JSX문법은 babel에 의해 react가 읽을 수 있는 코드인 createElement()로 변환된다.
babel을 통한 JSX문법 변환
아래의 코드는 우리가 흔히 사용하는 JSX문법을 사용한 리액트 코드이다.
const ACompo = () => {
return (
<div>
<p>ACompo</p>
</div>
)
}
const BCompo = () => {
return (
<div>
<p>BCompo</p>
</div>
)
}
const CCompo = () => {
return (
<>
<ACompo/>
<bcompo/>
</>
)
}
위의 코드는 babel의 @babel-plugin-transform-react.jsx
플러그인으로 인해 아래와 같은 코드로 변환된다.
변환 후 코드
위의 코드에서 /*#__PURE__*/_jsx
는 React.createElement
로 생각하면 된다.
babel의 Try it out에서 직접 코드를 입력하여 확인해 볼 수 있다.
번외) JSX없이 엘리먼트 만들기 (createElement만으로 엘리먼트 만들기)
그렇다면 번외로 처음부터 createElement
로 작성해도 잘 동작할까?
위의 그림과 같이 당연히(?) 잘 나오는 것을 볼 수 있다.
그 이유는 위에서 말했듯이 우리가 작성한 JSX문법
은 결국 createElement
로 변환하여 사용되기 때문이다.
대문자만 가능한 이유
그렇다면 본론으로 돌아와서 리액트 컴포넌트가 대문자만 사용 가능한 이유는 HTML태그와 컴포넌트를 분리하기 위해서 이다. 위의 변환 후 코드를 다시 살펴보자.
/*#__PURE__*/_jsx
는createElement
로 바꾸었다.
const ACompo = () => {
return createElement("div", {
children: createElement("p", {
children: "ACompo"
})
});
};
const BCompo = () => {
return createElement("div", {
children: createElement("p", {
children: "BCompo"
})
});
};
const CCompo = () => {
return createElements(_Fragment, {
children: [createElement(ACompo, {}), createElement("bcompo", {})]
});
};
CCompo
의 children
내부를 살펴보자.
[createElement(ACompo, {}), createElement("bcompo", {})]
createElement내부를 보면 대문자로 시작된 ACompo는 함수 그대로 들어가 있는데, bCompo는 문자열로 들어가있는 것을 볼 수 있다. 여기서 문자열로 변환된 곳이 또 있다. ACompo, BCompo의 내부도 “div”, 문자열로 들어가 있는 것을 볼 수 있다. 소문자로 시작된 것은 컴포넌트로 보지않고 HTML의 tag로 인지하여 문자열로 들어간다. 그래서 bCompo뿐만 아니라 div도 문자열로 들어가 있는 것이다. 대문자로 해야 우리가 작성한 함수가 그대로 들어가 컴포넌트 그대로를 인지할 수 있다.
결론
babel은 JSX에서 대소문자로 컴포넌트와 HTML 태그를 구분하여 변환한다. 그래서 컴포넌트로 사용할 때에는 대문자로 사용해야 원하는 컴포넌트를 화면에 노출 될 수 있도록 해야한다.