[REACT] JSX와 함께하는 마크업 작성

JSX란 무엇인가?

JSX는 JavaScript XML의 줄임말로, JavaScript 코드 내에서 HTML과 유사한 문법으로 UI를 작성할 수 있게 해주는 문법 확장입니다. React에서는 컴포넌트를 일반 JavaScript 함수로 정의하지만, JSX를 통해 그 함수 안에서 UI 구조를 직관적으로 선언할 수 있습니다.

HTML과 JSX의 핵심 차이점

  • 단일 루트 요소: JSX는 여러 요소를 반환할 때 반드시 하나의 부모 요소로 감싸야 합니다. <div>처럼 물리적인 컨테이너를 사용할 수도 있고, 불필요한 DOM 노드를 피하려면 Fragment (<>...</>)를 활용할 수도 있습니다.
  • 모든 태그는 닫혀야 함: HTML에서는 <br>이나 <hr> 같은 태그를 닫지 않아도 되지만, JSX에서는 반드시 <br />나 <hr />처럼 자기 닫힘(Self-closing) 형식을 사용해야 합니다.
  • camelCase 속성 표기: JSX는 JavaScript 환경에서 동작하므로 속성 이름이 camelCase로 작성됩니다. 예를 들어, class는 예약어이므로 className으로 작성하고, onclick 대신 onClick으로 표기합니다.
  • JavaScript 표현식 통합: JSX 내에서는 중괄호 {}를 사용해 JavaScript 표현식을 포함시킬 수 있습니다.

HTML에서 JSX로

HTML 코드

<div>
  <h2>웹 개발의 미래</h2>
  <img src="https://example.com/web.jpg" alt="웹 이미지">
  <p>현대 웹은 점점 더 동적인 경험을 제공합니다.</p>
</div>

JSX 코드

<div>
  <h2>웹 개발의 미래</h2>
  <img src="https://example.com/web.jpg" alt="웹 이미지" className="web-image" />
  <p>현대 웹은 점점 더 동적인 경험을 제공합니다.</p>
</div>

<img> 태그가 <img />로 자기 닫힘 형태로 바뀌고, className으로 수정됐습니다.

예제

ProfileCard.js

export default function ProfileCard() {
  const user = {
    name: "김민수",
    job: "프론트엔드 개발자",
    avatar: "https://example.com/avatar.jpg",
    bio: "React와 JSX를 사랑하는 개발자입니다."
  };

  return (
    <>
      <div className="profile-card">
        <img 
          src={user.avatar} 
          alt={`${user.name}의 아바타`} 
          className="avatar" 
        />
        <h3>{user.name}</h3>
        <p className="job">{user.job}</p>
        <p>{user.bio}</p>
        <button onClick={() => alert(`안녕하세요, ${user.name}입니다!`)}>
          인사하기
        </button>
      </div>
    </>
  );
}

App.js

import ProfileCard from './ProfileCard';

export default function App() {
  return (
    <div className="app">
      <h1>사용자 프로필</h1>
      <ProfileCard />
    </div>
  );
}

JSX 렌더링 활용

조건부 렌더링 추가

{} 안에서 삼항 연산자나 && 연산자를 사용해 조건부 콘텐츠를 쉽게 렌더링할 수 있습니다.

{user.bio ? <p>{user.bio}</p> : <p>소개글이 없습니다.</p>}

리스트 렌더링

배열과 map()을 활용해 반복적인 요소를 생성할 수 있습니다.

{skills.map((skill) => <li key={skill}>{skill}</li>)}