본문 바로가기
React

[React] JSX

by sssooon 2025. 5. 12.

JSX는 "JavaScript XML"의 약자, JS를 확장한 문법으로 JS 파일을 HTML과 비슷하게 마크업을 작성할 수 있도록 해준다.

JSX 내에서는 중괄호를 사용해 JS 변수, 함수, 표현식을 자유롭게 삽입할 수 있다.

하지만 JSX는 브라우저가 직접 이해하지 못하므로, Babel 같은 트랜스파일러가 JSX 코드를 일반 JS(React.createElement 등)로 변환한 뒤 실행한다.

 

컴포넌트를 작성하는 다른 방법도 있지만, 대부분 React 개발시에는 JSX의 간결함을 선호하며 대부분 코드 베이스를 JSX로 사용한다.

 

기존 Web은 HTML, CSS, JS를 기반으로 만들어 왔지만 이 시점에는 로직이 내용을 결정하는 경우가 많아졌다.

그래서 JS가 HTML을 담당하게 되었다.

이가 바로 React에서 렌더링 로직과 마크업이 같이 위치에 놓이게된 이유다.

 

 

JSX에 기존 HTML 코드를 그대로 붙여넣을시엔 동작하지 않는다.

JSX는 HTML 보다 더 엄격하고 규칙이 더 존재하기 때문이다.

 

규칙

1. 하나의 루트 엘리먼트로 반환하기

한 컴포넌트에서 여러 엘리먼트를 반환하기 위해서는 하나의 부모 태그로 감싸줘야한다.

JSX 태그를 하나로 감싸줘야하는 이유는, JSX가 HTML로 보이지만 내부적으로는 일반 JS 객체로 변환된다.

하나의 배열로 감싸지 않은 하나의 함수에서는 두개의 객체를 반환할 수 없다.

따라서 또 다른 태그나 Fragment로 감싸지 않으면 두개의 JSX 태그를 반환할 수 없다.

 

부모 태그로는 <div>를 사용할 수 있고 <div>를 추가 하기 싫다면 <></>으로 대체할 수 있다.

이 <></>, 빈 태그를 Fragment라고 한다. Fragments는 브라우저상의 HTML 트리 구조에 흔적을 남지기 않고 그룹화해준다.


2. 모든 태그는 닫아주기

JSX에서는 태그를 명시적으로 닫아야한다.

<img>처럼 자체적으로 닫아주는 태그는 반드시 <img />형태로 작성해야하며, <li>oranges와 같은 래핑 태그도 <li>oranges</li> 형태로 작성해야한다.

<>
  <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. 대부분 camel case로

JSX는 JS로 바뀌고 JSX에서 작성된 어트리뷰트는 JS 객체의 키가 된다.

컴포넌트에서 어트리뷰트를 변수로 읽는 경우가 있다. 그러나 JS는 변수명 제한이 있다.

예를 들면, 변수명에 대시를 포함하거나 class처럼 예약어를 사용할 수 없다.

<img
  src="https://i.imgur.com/yXOvdOSs.jpg"
  alt="Hedy Lamarr"
  className="photo"
/>

 


중괄호가 있는 JSX 내부에서 JS 사용하기

JSX를 사용하면 JS 파일에 HTML과 비슷한 마크업을 작성하여 렌더링 로직과 콘텐츠를 같은 곳에 놓을 수 있다.

때로는 JS 로직을 추가하거나 해당 마크업 내부의 동적인 프로퍼티를 참조하고 싶을때가 있다.

이 상황에서 JSX는 중괄호를 사용하여 JS를 사용할 수 있다.

 

따옴표로 문자열 전달하기

문자열 어트리뷰트를 JSX에 전달하려면 작은따옴표나 큰따옴표로 묶어야한다.

export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}

 

src와 alt를 동적으로 지정하기 위해선 ""를 {}로 바꿔 JS의 값을 사용할 수 있다.

export default function Avatar() {
  const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}

 

CSS 클래스 이름을 지정하는 className="avatar"와 avatar라는 JS 변수 값을 읽는 src={avatar}의 차이점에 주목해야한다.

중괄호를 사용하면 마크업에서 바로 JS를 사용할 수 있기 때문이다


중괄호 사용하기 : JS 연결

중괄호 사이에서 JS를 사용할 수 있다.

아래 예는 name을 선언한 다음 <h1> 내부에 중괄호로 포함한다.

export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}

 

name 변수의 값을 변경시에 To Do List 제목은 계속 변경된다.

 

formatDate()와 같은 함수 호출을 포함해 모든 JS 표현식은 중괄호 사이에 작동한다.

const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'en-US',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}

 

JSX안에서 중괄호는 두가지 방법으로만 사용할 수 있다.

1. JSX 태그 안의 문자 : <h1>{name}'s To Do List</h1>는 작동하지만, <{tag}>Gregorio Y. Zara's To Do List</{tag}>는 작동하지 않는다.

2. = 바로 뒤에 오는 어트리뷰트 : src={avatar} avatar 변수를 읽지만 src="{avatar}" "{avatar}" 문자열을 전달한다.


이중 중괄호 사용하기 : JSX의 CSS와 다른 객체

JSX에는 문자열, 숫자 및 기타 JS 표현식뿐만 아니라 객체를 전달할 수도 있다.

객체는 { name: "Hedy Lamarr", inventions: 5 }처럼 중괄호로 표시된다.

따라서 JSX에서 객체를 전달하려면 person={{ name: "Hedy Lamarr", inventions: 5 }}와 같이 다른 중괄호 쌍으로 객체를 감싸야한다.

 

JSX의 인라인 CSS 스타일에서도 볼 수 있다. React에서 인라인 스타일을 사용할 필요가 없다.

그러나 인라인 스타일이 필요할 때 style 어트리뷰트에 객체를 전달해야한다.

export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Improve the videophone</li>
      <li>Prepare aeronautics lectures</li>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}

 

인라인 style 프로퍼티는 camelCase로 작성된다.

예를 들어 HTML에서 <ul style="background-color: black">은 컴포넌트에서 <ul style={{ backgroundColor: 'black' }}>로 작성된다.


JS 객체와 중괄호

여러 표현식을 하나의 객체로 옮기고 중괄호 안의 JSX에서 참조할 수 있다.

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

 

위의 예시에서 person 객체는 name 문자열과 theme 객체를 포함한다.

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

 

컴포넌트 내에서 person값을 아래와 같이 사용할 수 있다.

<div style={person.theme}>
  <h1>{person.name}'s Todos</h1>

 

어트리뷰트를 객체를 결합하는 방법은 아래 예시를 참고한다.

const baseUrl = 'https://i.imgur.com/';
const person = {
  name: 'Gregorio Y. Zara',
  imageId: '7vQD0fP',
  imageSize: 's',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src={baseUrl+person.imageId+person.imageSize+".jpg"}
        alt={person.name}
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

 

 

'React' 카테고리의 다른 글

[React] 컨포넌트에 props 전달  (1) 2025.05.12
[React] 컴포넌트  (0) 2025.05.12
[React] Vite로 React 시작하기  (0) 2024.10.25
[React] React란  (0) 2024.10.25