2-1. JSX란?
JSX란?
const element = <h1>Hello, world!</h1>;
JSX(JavaScript XML), JavaScript에 XML을 추가하여 확장한 문법
브라우저는 JSX를 알고있을까?
JSX가 포함된 코드를 아무런 처리 없이 그대로 실행하면 에러가 발생한다.
JSXS는 자바스크립트 표준 코드가 아닌 페이즈북이 임의로 만든 새로운 문법이기 때문에 반드시 트랜스파일러를 거쳐야 비로소 자바스크립트 런타임이 이해할 수 있는 의미있는 코드로 변환된다.
JSX는 어떻게 자바스크립트로 변환될까?
우선 JS가 JSX로 변환되는 방식을 알려면 리액트에서 JSX를 변환하는 @babel/plugin-transform-react-jsx
플러그인을 알아야 한다.
이 플러그인은 JSX 구문을 자바스크립트가 이해할 수 있는 형태로 변환한다.
// JSX
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
// JS로 변환된 JSX
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
JSX의 설계 목적
다양한 트랜스파일러에서 다양한 속성을 가진 트리 구조를 토큰화해 ECMAScript로 변환하는데 초점을 두고 있다.
트리 구조로 표현하고 싶은 다양한 것들을 작성
HTML, XML이외에도 다른 구문으로도 확장될 수 있도록, 개발자들에게 친숙함을 느낄 수 있기 위해
JSX 정의
1. JSXElement
JSX를 구성하는 가장 기본적인 요소로, HTML element와 비슷한 역할을 한다.
JSXOpeningElement: <div>
JSXClosingElement: </div>
JSXSelfClosingElement: <div />
JSXFragment: <></>
❓ 컴포넌트 명이 대문자로 시작해야 하는 이유는 무엇인가요?
리액트에서 HTML 구문 이외 사용자 정의 컴포넌트는 반드시 대문자로 시작해야 사용가능하다. 이는 HTML 태그명과 사용자가 만든 컴포넌트 태그명을 구분 짓기 위해서다.
// HTML 태그명
<span></span>
// 컴포넌트명
<Span></Span>
JSXElementName
JSXElement의 요소 이름으로 쓸 수 있는 것을 의미한다.
JSXIdentifier:
$
와_
외에 다른 특수문자나 숫자로 시작할 수 없다.JSXNamespacedName: JSXIdentifier:JSXIdentifier의 조합, 두 개 이상은 불가
JSXMemberExperssion: JSXIdentifier.JSXIdentifier의 조합, 두 개 이상 가능
2. JSXAttributes
JSXElement에 부여할 수 있는 속성을 의미한다. 필수값이 아니고, 존재하지 않아도 에러가 발생하지 않는다.
JSXSpreadAttributes
{…AssignmentExpression}
단순히 객체뿐만 아니라 자바스크립트에서 AssignmentExpression로 취급되는 모든 표현식 존재 가능
조건문 표현식
화살표 함수
할당식
JSXAttribute
JSXAttributeName - JSXAttributeValue로 짝을 이루어 표현
JSXAttributeName: 속성의 키 값
JSXAttributeValue
큰 따옴표로 구성된 문자열
작은 따옴표로 구성된 문자열
{ AssignmentExpression }
JSXElement: 값으로 다른 JSX요소가 들어갈 수 있다.
<aside> 💡 값을 전달할 때 { }로 감싸는게 리액트의 문법으로 오해하는 개발자들이 있다.
이는 리액트의 문법이 아닌 prettier의 규칙이다. prettier 규칙은 태그가 포함된 JSX 구문을 좀 더 읽기 쉽게 만들기 위해 제공된다.
<div attribute=<div>hello</div> /> <div attribute={<div>hello</div>} />
</aside>
JSXFragment
3. JSXChildren
JSXElement의 자식 값을 나타낸다.
JSXChild: JSXChildren을 이루는 기본 단위다. JSXChildren은 JSChild가 없어도 상관없다.
JSXText: 문자열
JSXElement: 다른 JSX요소
JSXFragment: 빈 요소
{JSXChildExpression (optional)}
// 해당 컴포넌트를 렌더링하면 "foo"라는 문자열이 출력된다. return <>{(()=> 'foo')()}</>
4. JSXStrings
HTML에서 사용 가능한 문자열은 모두 JSXStrings에서도 가능하다.
큰따옴표로 구성된 문자열
작은 따옴표로 구성된 문자열
JSXText
💡 자바스크립트와는 한 가지 중요한 차이점이 발생하는데 바로 \\
로 시작하는 이스케이프 문자 형태소다.
\\
는 자바스크립트에서 특수문자를 처리할 때 사용되므로 몇 가지 제약사항이 있지만, HTML에서 아무런 제약없이 사용할 수 있다.
따라서 JSX에서는 HTML처럼 \\
을 이스케이프 문자열로 처리하고 있지 않다.
마무리
이처럼 JSX는 자바스크립트 코드 내부에 HTML과 같은 트리 구조를 가진 컴포넌트를 표현할 수 있다는 점에 각광받고 있다.
물론 JSX가 HTML문법과 자바스크립트 문법이 뒤섞여서 코드의 가독성을 해친다는 의견도 있다. JSX 내부에 자바스크립트 문법이 많아질수록 복잡성이 증대하면서 코드의 가독성도 해칠 것이므로 주의해서 사용해야 한다.