JSX — HTML인 듯 HTML이 아닌 그 문법
Article
React를 처음 접하면 가장 먼저 눈에 들어오는 게 있습니다. 자바스크립트 파일 안에 HTML처럼 생긴 코드가 들어있는 것입니다.
function Welcome() {
return <h1>안녕하세요!</h1>;
}
이게 JSX입니다. JavaScript XML의 약자인데, 이름보다 중요한 건 HTML과 뭐가 다른지 아는 것입니다.
JSX는 JavaScript 안에서 쓰는 마크업입니다
퍼블리셔가 만드는 HTML은 .html 파일에 들어갑니다. JSX는 .jsx 또는 .tsx 파일, 즉 자바스크립트 파일 안에 들어갑니다.
이게 가능한 이유는, JSX가 실제로 자바스크립트 코드로 변환되기 때문입니다.
// 우리가 쓰는 JSX
<h1 className="title">안녕하세요</h1>
// 브라우저가 실행하는 실제 코드
React.createElement("h1", { className: "title" }, "안녕하세요")
JSX는 React.createElement()를 보기 좋게 쓰기 위한 문법입니다. 빌드 과정에서 자동으로 변환되니까 개발자는 편하게 HTML과 비슷한 형태로 쓰면 됩니다.
HTML과 다른 점 — 이것만 기억하세요
퍼블리셔에게는 좋은 소식이 있습니다. JSX는 HTML과 거의 같습니다. 다른 점 몇 가지만 기억하면 됩니다.
1. class 대신 className
HTML에서 가장 많이 쓰는 class 속성이 JSX에서는 className으로 바뀝니다.
// HTML
<div class="container">...</div>
// JSX
<div className="container">...</div>
이유는 간단합니다. class가 자바스크립트에서 예약어이기 때문입니다. 자바스크립트에서 class는 클래스를 선언할 때 쓰는 키워드라서 충돌을 피하기 위해 className을 씁니다.
2. for 대신 htmlFor
<label> 태그에서 쓰는 for 속성도 마찬가지입니다.
// HTML
<label for="email">이메일</label>
// JSX
<label htmlFor="email">이메일</label>
for도 자바스크립트 예약어(반복문)라서 htmlFor로 바꿔 씁니다.
3. 닫는 태그가 필수입니다
HTML에서는 <img>, <br>, <input> 같은 태그를 닫지 않아도 됩니다. JSX에서는 모든 태그를 반드시 닫아야 합니다.
// HTML — 닫지 않아도 OK
<img src="photo.jpg" alt="사진">
<br>
<input type="text">
// JSX — 반드시 닫아야 함
<img src="photo.jpg" alt="사진" />
<br />
<input type="text" />
슬래시(/)를 빼먹으면 에러가 납니다. 처음에는 귀찮지만 금방 습관이 됩니다.
4. 중괄호로 자바스크립트를 쓸 수 있습니다
이게 JSX의 가장 강력한 기능입니다. 중괄호 {} 안에 자바스크립트 표현식을 넣을 수 있습니다.
const name = "민초리";
const today = new Date().toLocaleDateString();
return (
<div>
<h1>{name}님, 환영합니다!</h1>
<p>오늘은 {today}입니다.</p>
<p>1 + 1 = {1 + 1}</p>
</div>
);
HTML에서는 불가능한 일입니다. HTML은 정적인 텍스트일 뿐이니까요. JSX에서는 변수 값을 직접 넣고, 계산도 하고, 함수도 호출할 수 있습니다.
5. 스타일은 객체로 씁니다
HTML의 인라인 스타일은 문자열입니다. JSX에서는 객체로 씁니다.
// HTML
<div style="background-color: red; font-size: 16px;">...</div>
// JSX
<div style={{ backgroundColor: "red", fontSize: "16px" }}>...</div>
중괄호가 두 겹인 이유는, 바깥 중괄호는 "자바스크립트 쓸 거야"라는 의미이고, 안쪽 중괄호는 자바스크립트 객체를 나타내기 때문입니다. CSS 속성명은 케밥 케이스(background-color) 대신 카멜 케이스(backgroundColor)로 씁니다.
하나 더 — 최상위 요소는 하나여야 합니다
JSX에서 여러 요소를 반환할 때는 하나의 부모 요소로 감싸야 합니다.
// 에러 — 최상위 요소가 2개
return (
<h1>제목</h1>
<p>내용</p>
);
// OK — div로 감쌈
return (
<div>
<h1>제목</h1>
<p>내용</p>
</div>
);
// OK — Fragment로 감쌈 (불필요한 div를 피할 수 있음)
return (
<>
<h1>제목</h1>
<p>내용</p>
</>
);
<>...</>는 Fragment라고 부르는데, 실제 DOM에는 아무 요소도 추가하지 않으면서 여러 요소를 묶어주는 역할을 합니다. 불필요한 div가 생기는 걸 피할 수 있어서 자주 쓰입니다.
차이점 한눈에 보기
| HTML | JSX |
|---|---|
class |
className |
for |
htmlFor |
<img> (닫기 선택) |
<img /> (닫기 필수) |
| 정적 텍스트만 | {변수}, {표현식} 사용 가능 |
style="color: red" |
style={{ color: "red" }} |
| 최상위 요소 제한 없음 | 최상위 요소 하나 필수 |
퍼블리셔에게 JSX는 어렵지 않습니다
솔직히 말하면, JSX는 HTML을 이미 아는 사람에게 가장 쉬운 React 개념입니다. 차이점이 몇 가지 안 되고, 그마저도 규칙이 명확합니다.
처음에는 className 쓰는 게 어색하고, 닫는 태그에 슬래시 넣는 게 귀찮게 느껴질 수 있습니다. 하지만 며칠만 써보면 완전히 자연스러워집니다.
다음 글에서는 React의 핵심 단위인 컴포넌트에 대해 알아보겠습니다. HTML의 include나 partial과 비슷하지만, 훨씬 더 강력한 개념입니다.