학습 자료

JSX — HTML처럼 생겼지만 자바스크립트다


Article

앞 강의에서 return <h1>안녕</h1>;이라고 썼다. 자바스크립트에 이런 문법은 없다.

이게 JSX다. 이름은 JavaScript XML의 줄임말이고, 정체는 자바스크립트다.

실제로는 함수 호출이다

빌드 도구가 JSX를 무엇으로 바꾸는지 보면 오해가 사라진다.

const element = <h1 className="title">안녕</h1>;

이 코드는 변환을 거쳐 이렇게 된다.

const element = React.createElement("h1", { className: "title" }, "안녕");

그리고 createElement가 돌려주는 건 그냥 객체다.

{
  type: "h1",
  props: { className: "title", children: "안녕" }
}
JSX 의 정체
  1. <h1>안녕</h1>우리가 쓰는 것
  2. createElement()빌드 도구가 바꾼다
  3. 자바스크립트 객체React 가 다루는 것

이 사실을 알면 나머지가 전부 설명된다. JSX는 이다. 변수에 담고, 배열에 넣고, 함수가 반환할 수 있다.

const title = <h1>안녕</h1>;
const list = [<li>하나</li>, <li></li>];

function getTitle() {
  return <h1>안녕</h1>;
}

자바스크립트 편 11강에서 "함수는 값이다"라고 했던 것과 같은 이야기다.

중괄호 — 자바스크립트로 돌아가는 문

JSX 안에서 자바스크립트를 쓰려면 중괄호를 연다.

function Greeting() {
  const name = "지원";
  const age = 27;

  return (
    <div>
      <h1>안녕, {name}</h1>
      <p>내년이면 {age + 1}살</p>
      <p>{name.toUpperCase()}</p>
      <p>{age >= 19 ? "성인" : "미성년자"}</p>
    </div>
  );
}

중괄호 안에는 값이 되는 것이라면 무엇이든 들어간다. 변수, 계산식, 함수 호출, 삼항 연산자.

들어갈 수 없는 것도 있다.

중괄호 안에 넣을 수 있는 것

가능

값이 되는 것 (표현식)

  • {name} — 변수
  • {age + 1} — 계산식
  • {getName()} — 함수 호출
  • {a ? b : c} — 삼항 연산자
  • {list.map(...)} — 메서드 체이닝

불가능

값이 안 되는 것 (문)

  • {if (a) {...}} — if 문
  • {for (...) {...}} — for 문
  • {const x = 1} — 변수 선언
  • 삼항 연산자나 map 으로 바꿔 쓴다

if문은 값을 만들지 않고 실행만 한다. 그래서 중괄호에 넣을 수 없다. 자바스크립트 편 8강에서 "if문은 실행하고, 삼항 연산자는 값을 낸다"고 구분한 이유가 여기서 드러난다.

무엇이 화면에 보이나

중괄호에 넣은 값의 타입에 따라 화면에 나오는 게 다르다. 헷갈리는 부분이다.

function Test() {
  return (
    <div>
      <p>{42}</p>
      <p>{"글자"}</p>
      <p>{true}</p>
      <p>{null}</p>
      <p>{undefined}</p>
      <p>{[1, 2, 3]}</p>
      <p>{0}</p>
    </div>
  );
}
화면에비고
4242숫자는 그대로
"글자"글자문자열도 그대로
true / false(아무것도 안 나옴)boolean 은 무시된다
null / undefined(아무것도 안 나옴)무시된다
[1, 2, 3]123배열은 펼쳐서 이어붙인다
00숫자라서 보인다 — 주의

마지막 줄이 함정이다. 자바스크립트 편 7강에서 0이 falsy라고 배웠는데, React는 0을 화면에 그린다.

function Cart({ items }) {
  return <div>{items.length && <p>담긴 상품이 있다</p>}</div>;
}

items가 빈 배열이면 items.length0이다. 0 && ...0을 돌려주고(자바스크립트 편 6강의 단축 평가), React는 그 0을 화면에 찍는다. 아무것도 없어야 할 자리에 0이 나타난다.

HTML 과 다른 점

JSX는 자바스크립트라서 HTML과 어긋나는 지점이 있다.

class 가 아니라 className

class는 자바스크립트의 예약어다. 자바스크립트 편 19강에서 클래스를 만들 때 쓴 그 키워드다. 그래서 이름을 바꿨다.

<div className="card">…</div>

같은 이유로 forhtmlFor가 된다.

속성은 카멜 케이스

HTMLJSX이유
classclassNameclass 는 예약어
forhtmlForfor 는 예약어
onclickonClick카멜 케이스
tabindextabIndex카멜 케이스
maxlengthmaxLength카멜 케이스

data-*aria-*는 예외다. 하이픈 그대로 쓴다.

모든 태그를 닫는다

HTML에서 허용되던 열린 태그가 JSX에서는 에러다.

<br />
<img src="a.png" alt="" />
<input type="text" />

<br>이 아니라 <br />이다. XML 규칙을 따르기 때문이다.

스타일은 객체로

<div style={{ color: "red", fontSize: "16px" }}>빨강</div>

중괄호가 두 개다. 바깥은 JSX의 중괄호, 안쪽은 객체 리터럴의 중괄호다.

속성명도 카멜 케이스다. font-sizefontSize가 된다. 하이픈은 자바스크립트에서 뺄셈으로 읽히기 때문이다.

흔히 만나는 실수

JSX 에서 자주 막히는 곳
  1. 01

    return 뒤에 줄바꿈

    자바스크립트가 세미콜론을 자동으로 넣어 undefined 를 반환해버린다. 여러 줄이면 괄호로 감싼다.

    return (
      <div></div>
    );
  2. 02

    주석은 중괄호 안에

    JSX 안에서 // 는 화면에 글자로 찍힌다.

    {/* 이렇게 쓴다 */}
  3. 03

    중괄호 안에 문을 넣기

    iffor 는 값이 아니다. 삼항이나 map 으로 바꾼다.

    {isLogin ? <Home /> : <Login />}

첫 번째는 정말 자주 겪는다.

function App() {
  return
    <h1>안녕</h1>;
}

return 뒤에서 문장이 끝난 것으로 처리되어 아무것도 반환하지 않는다. 자바스크립트 편 2강에서 "세미콜론을 자동으로 붙여준다"고 했던 게 여기서 사고를 친다.

정리하면

  • JSX는 HTML이 아니다. createElement() 호출로 바뀌고, 결과는 자바스크립트 객체다.
  • 그래서 JSX는 이다. 변수에 담고 함수가 반환한다.
  • 중괄호 안에는 값이 되는 것만 넣는다. iffor는 못 넣는다.
  • boolean, null, undefined는 화면에 안 나오지만 0은 나온다. && 앞에 숫자를 두지 않는다.
  • classclassName, 속성은 카멜 케이스, 모든 태그를 닫는다.
  • return 뒤에 줄을 바꾸려면 괄호로 감싼다.

다음 강의부터 Part 2다. 컴포넌트를 어떤 기준으로 나누는지 본다.

JSX — HTML처럼 생겼지만 자바스크립트다 — 디코드랩(DCODELAB)