JSX 개념

#React

JSX란?

JSX(JavaScript XML)는 자바스크립트 코드 안에서 HTML과 비슷한 문법을 사용해 UI를 정의할 수 있도록 도와주는 문법 확장(synatatic extension)입니다. 쉽게 말해, 자바스크립트 안에서 HTML 처럼 생긴 코드를 쓸 수 있게 해주는 문법입니다.

JSX는 js의 문법 확장이므로 js 내부에서는 어디에서든 사용할 수 있다. 예를 들어 변수에 JSX를 저장해서 리턴 내부에서 사용하는 것도 가능하다.

export default function App()
{
  const hello_react = <h1>Hello, React!</h1>
  return(
    <div>{ hello_react }</div>
  );
}

JSX를 반드시 써야하는 것은 아니다. 원래는 리액트의 createElement 메서드가 원형인데, createElement 메서드를 사용하는 것이 상대적으로 복잡해서 JSX를 만들었다고 한다.

// createElement
React.createElement(
  'div',
  null,
  React.createElement('h1', null, 'Hello, React!')
);

// 같은 코드를 JSX로
<div>
  <h1>Hello, React!</h1>
</div>

리액트 코드를 컴파일하면 JSX -> createElement 호출(js)로 변환되고, 이 호출 결과 생성된 React 엘리먼트 객체들이 가상 DOM의 바탕이 된다.

JSX 사용 규칙

JSX를 사용할 때는 규칙이 여러가지 있는데, createElement와 관련된 규칙은 반드시 하나의 상위 태그만 있어야한다는 것이다. 즉 컴포넌트를 리턴할 때, 전체를 한 번에 감싸는 상위태그 하나만 리턴해야한다. 왜냐하면 상위 태그가 하나여야 createElement로 변환되었을 때 하나의 객체가 리턴되기 때문이다.

하지만 <div> 등으로 여러 개의 태그를 묶으면 사용하지 않는 불필요한 태그가 늘어나는 상황이 발생한다. 그래서 리액트 프래그먼트라는 것이 존재한다. 리액트 프래그먼트는 <React.Fragment><React.Fragment/> 또는 <></>로 사용할 수 있다. 프래그먼트를 사용하면 나중에 리액트에서 dom으로 변환할 때 프래그먼트는 무시하고 하위 요소들만 변환한다.

그리고 JSX에서 html 속성을 바로 쓸 수 없는 경우가 있다. js의 예약어와 이름이 겹치는 경우인데, 예를 들어 class의 경우에는 className으로 jsx 내부에서 사용해야 한다. 예약어와 완전히 이름이 겹치는 경우가 아니면 보통 html 속성 이름을 카멜 케이스로 변환해서 사용한다. style은 style 이름 그대로 사용하지만, 값을 인라인 텍스트로 넣는 것이 아니라 객체로 넣어야하고, style 내부 객체의 속성 값도 카멜 케이스를 따라야한다.

<h1 style={{color: "red", backgroundColor: "lightgray"}}>Styled Text</h1>

style에 객체를 넣을 때 중괄호를 사용했는데, 이처럼 jsx에서 중괄호를 쓰면 js 표현식을 사용할 수 있다. 삼항연산자나 논리연산자를 사용하여 jsx를 show/hide하는 것도 가능하다.

jsx에서 주석은 {/* */} 형태로 처리하며, jsx는 html과 달리 모든 태그를 닫아서 사용해야한다.

JSX의 문법적 특징(요약)

  1. 하나의 루트 요소로 반환하기
  2. 모든 태그 닫기
  3. 태그 속성은 카멜 케이스로 작성하기
  4. 표현식은 중괄호 안에서 사용하기
  5. 인라인 스타일은 객체로 지정하기
  6. 중괄호 안에 주석 작성하기