JSX는 자바스크립트 파일 안에서 HTML과 같은 마크업을 사용할 수 있도록 만들어주는 자바스크립트 문법 확장자예요. 컴포넌트를 작성하는 많은 방법들이 있음에도 불구하고 대부분의 리액트 개발자들은 JSX의 간결함을 좋아하고 많은 코드베이스가 이를 사용해요.
이 페이지에서는
- 왜 리액트가 렌더링 로직을 마크업과 함께 사용하는지
- JSX는 HTML과 어떻게 다른지
- JSX로 정보를 어떻게 보여주는지
를 알아볼 거예요.
JSX: Putting markup into JavaScript | JSX: 자바스크립트에 마크업 넣기
웹은 HTML, CSS 그리고 자바스크립트로 만들어져요. 수년동안 웹 개발자들은 보통 분리된 파일로 HTML로 콘텐츠를 만들고, CSS로 디자일을 하고, 자바스크립트로 로직을 만들었어요! 콘텐츠는 HTML 안에서 표시되고 페이지의 로직은 자바스크립트에서 별개로 구성되어있어요.
![]() |
![]() |
HTML | JavaScript |
그러나 웹에서 상호작용이 점점 늘어나면서 로직이 콘텐츠를 결정하는 경우가 점점 증가했어요. 자바스크립트가 HTML을 담당해요! 이것이 바로 리액트에서 렌더링 로직과 마크업이 한 곳, 컴포넌트 안에 함께 있는 이유예요.
![]() |
![]() |
<Sidebar.js> React Component |
<Form.js> React Component |
버튼의 렌더링 로직과 마크업을 함께 두는 것은 그것들이 변경사항이 있을 때마다 서로 동기화된다는 것을 보장해요. 반대로, 버튼의 마크업과 사이드바의 마크업과 같이 서로 연관되지 않은 세부적인 요소들은 각각 독립되어 있어서 각각의 변동사항이 서로에게 영향을 미치지 않는 안전한 상태를 만들어줘요.
각각의 리액트 컴포넌트는 리액트가 브라우저에서 렌더링하는 마크업을 포함하는 자바스크립트 함수예요. 리액트 컴포넌트는 마크업을 표시하기 위해 JSX라고 불리는 문법 확장자를 사용해요. JSX는 HTML과 거의 비슷하지만 조금 더 엄격하고 동적인 정보를 보여줄 수 있어요. 이를 이해하는 가장 좋은 방법은 HTML 마크업을 JSX 마크업으로 바꿔보는 것이에요.
NOTE
JSX와 리액트는 달라요. 이 둘은 보통 같이 사용되지만 각각 독랍적으로 사용할 수 있어요.
Converting HTML to JSX | HTML을 JSX로 바꾸기
(완전히 유효한) HTML 코드가 있다고 생각해보세요.
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Invent new traffic lights
<li>Rehearse a movie scene
<li>Improve the spectrum technology
</ul>
그리고 컴포넌트에 이것을 넣어보세요.
export default function TodoList() {
return (
// ???
)
}
만약 그대로 복사해서 붙여넣는다면 동작하지 않아요.
JSX가 더 엄격하고 HTML보다 조금 더 많은 규칙이 있기 때문에 이런 오류가 발생해요. 만약 위의 에러 메시지를 읽는다면 마크업을 고치는데 도움이 되고 그렇지 않다면 아래의 가이드를 따를 수도 있어요.
NOTE
대부분 화면에 보이는 리액트 에러 메시지는 문제가 난 곳을 찾는데 도움이 돼요. 문제가 생기면 메시지를 읽어보세요!
The Rules of JSX | JSX 규칙
1. Return a single root element | 단일 루트 엘리먼트를 반환하세요.
컴포넌트에서 여러 엘리먼트를 반환하려면 단일 부모 태그로 이들을 감싸세요.
예를 들어, <div>
를 사용할 수 있어요.
<div>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>
추가적은 <div>
를 마크업에 넣고 싶지 않다면 대신 <>
와 </>
를 사용할 수 있어요.
<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>
이 비어있는 태그는 Fragment라고 해요. Fragment는 브라우저의 HTML 트리에는 나오지 않도록 구성물들을 그룹핑해줘요.
왜 여러개의 JSX 태그는 감싸져야 할까요?
JSX은 HTML처럼 생겼지만 실제로는 기본 자바스크립트 객체로 변환돼요. 배열로 감싸지 않고서 한 함수에서 두개의 객체를 반환할 수 없어요. 이는 두 개의 JSX 태그를 다른 태그나 Fragment로 감싸지 않으면 반환할 수 없는 이유를 설명해줘요.
2. Close all the tags | 모든 태그를 닫으세요.
JSX는 명시적으로 닫아야만 해요. 예를 들어 <img>
와 같은 셀프 클로징 태그는 <img />
로, <li>oranges
와 같은 래핑 태그는 <li>oranges</li>
로 작성하세요.
Hedy Lamarr의 사진과 리스트 아이템이 닫힌 모습이에요.
<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve the spectrum technology</li>
</ul>
</>
3. camelCase -all- most of the things! | 대부분은 카멜케이스로!
JSX는 자바스크립트로 변하고 JSX로 작성된 속성들은 자바스크립트 객체의 키가 돼요. 컴포넌트에서 여러분은 이 속성들을 변수로 작성하고 싶을 수 있어요. 그러나 자바스크립트는 변수명에 제약사항이 있어요. 예를 들어 대시(-)를 포함해서는 안되고 class
와 같은 예약어를 사용할 수 없어요.
리액트에서 많은 HTML과 SVG가 카멜케이스로 작성된 이유가 바로 이 때문이에요. 예를 들어, stroke-width
대신 strokeWidth
를 사용해요. class
는 예약어이기 때문에 리액트에서는 해당 DOM 속성에 따라 className
을 사용하고 있어요.
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>
DOM 컴포넌트 prop의 목록 안에서 이 속성들을 찾을 수 있어요. 만약 무언가 잘못되었더라도 걱정하지 마세요. 리액트가 브라우저 콘솔창에 가능한 해결 방법과 함께 메시지를 보여줄게요.
함정
역사적 이유로, aria-*와 data-* 속성은 HTML에서도 대시와 함께 작성돼요.
Pro-tip: Use a JSX Converter | 팁: JSX 변환기를 사용하세요
모든 속성을 존재하는 마크업으로 바꾸는 것은 굉장히 지루해요! 이미 작성되어 있는 HTML과 SVG를 JSX로 번역하는데 변환기를 사용하는 것을 추천해요. 변환기는 실제로 굉장히 유용하지만 편하게 JSX를 사용하기 위해 내용을 이해하는 것은 가치가 있어요.
여기 최종 결과예요.
Recap | 요약
이제 여러분은 JSX의 존재 이유와 컴포넌트 안에서의 사용 방법을 알게 되었어요.
- 리액트 컴포넌트는 서로 관련있는 렌더링 로직과 마크업을 한 번에 묶어요.
- JSX는 HTML과 비슷하지만 몇 가지 차이가 있어요. 필요하다면 변환기를 사용할 수 있어요.
- 에러 메시지는 마크업을 수정하는 방법을 알려줘요.
Challengs | 도전과제
1. Convert some HTML to JSX | HTML을 JSX로 바꾸기
이 HTML은 컴포넌트로 붙여넣어졌지만 유효한 JSX는 아니에요. 수정해보세요.
직접 해도 되고, 변환기를 사용해도 돼요!