JSX의 개념과 동작 원리

Kingmo·2022년 3월 14일

React를 다룰 때 가장 먼저 마주치는 문법이 바로 JSX다.

1. JSX(JavaScript XML)란?

JSX는 자바스크립트의 확장 문법으로, JavaScript 코드 안에서 UI 구조를 직관적으로 마크업할 수 있도록 설계되었다.

const element = <h1>Hello, world!</h1>;

얼핏 보면 HTML 태그를 자바스크립트 변수에 바로 할당한 것처럼 보이지만, 문자열도 HTML도 아니다. 이는 빌드 타임에 순수 자바스크립트로 변환되는 확장 문법이다.

2. JSX 안에 자바스크립트 표현식 넣기

JSX 내부에서는 중괄호({ })를 사용하여 유효한 자바스크립트 표현식(변수, 함수 호출, 연산 등)을 자유롭게 삽입할 수 있다.

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);
  • 산술 연산({ 1 + 1 }), 문자열 조합, 함수 호출 결과({ formatName(user) }) 등 값을 반환하는 모든 표현식이 중괄호 안에 들어갈 수 있다.

3. JSX 자체가 하나의 표현식(Expression)이다

컴파일 과정을 거치면 JSX는 일반 자바스크립트 함수 호출 결과이자 순수 객체로 평가된다.

따라서 JSX는 변수에 할당할 수 있고, if 조건문이나 for 반복문 내부에서 사용할 수 있으며, 함수의 인자로 전달하거나 반환값으로 리턴할 수 있다.

function getGreeting(user) {
  // if문 분기에 따라 서로 다른 JSX 반환 가능
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

4. 속성(Attribute) 정의 규칙

속성값을 지정할 때는 정적 문자열인지, 자바스크립트 표현식인지에 따라 구분한다.

  • 정적 문자열 리터럴: 따옴표(" ") 사용
    const element = <div tabIndex="0"></div>;
  • 동적 자바스크립트 표현식: 중괄호({ }) 사용
    const element = <img src={user.avatarUrl} />;

카멜 케이스(camelCase) 네이밍 규칙

JSX는 HTML보다 자바스크립트에 가깝다. class나 for 같은 단어는 자바스크립트의 예약어이므로, React DOM은 HTML 어트리뷰트 대신 camelCase 컨벤션을 사용한다.

  • class →\rightarrow className
  • tabindex →\rightarrow tabIndex
  • onclick →\rightarrow onClick

5. 자식 요소 정의와 Self-Closing 태그

태그 사이에 자식(Children) 노드가 없는 빈 태그라면, XML 문법처럼 반드시 끝에 슬래시(/)를 붙여 닫아주어야 한다(Self-closing).

// 닫는 태그 필수
const element = <img src={user.avatarUrl} />;

물론 일반 태그처럼 하위에 여러 자식 요소를 중첩하여 구성할 수도 있다.

const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

(단, 최상위에는 반드시 단 하나의 루트 태그 또는 React Fragment(<> ... </>)가 감싸고 있어야 한다.)

6. XSS(크로스 사이트 스크립팅) 인젝션 방어

React DOM은 JSX 내에 포함된 모든 값을 렌더링하기 전에 기본적으로 문자열로 이스케이프(Escape) 처리한다.

const title = response.potentiallyMaliciousInput; // 악성 스크립트가 담긴 문자열

// React가 태그를 텍스트로 안전하게 변환하므로 script 실행이 차단된다.
const element = <h1>{title}</h1>;

사용자가 입력한 악의적인 HTML 태그나 자바스크립트 코드가 그대로 브라우저에 파싱되어 실행되는 XSS 공격을 별도 처리 없이도 사전에 방어할 수 있다.

7. JSX의 이면: React.createElement()

브라우저는 JSX 문법을 직접 해석할 수 없다. 따라서 Babel과 같은 트랜스파일러가 빌드 시점에 JSX를 React.createElement() 함수 호출로 변환한다.

아래 두 코드는 완전히 동일한 동작을 수행한다.

// 1. 개발자가 작성한 JSX
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

// 2. Babel 변환 후 실제 실행되는 자바스크립트 코드
const element = React.createElement(
  'h1',
  { className: 'greeting' },
  'Hello, world!'
);

React.createElement()가 호출되면 다음과 같은 형태의 경량 자바스크립트 객체가 생성된다.

// 단순화된 React Element 객체 형태
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

이 객체를 "React Element(리액트 엘리먼트)"라고 부른다. 화면에 띄워야 할 UI의 설계도 역할을 하는 가벼운 객체이며, React는 이 객체를 기반으로 Virtual DOM을 형성하고 실제 브라우저 DOM을 효율적으로 조작한다.

profile
Developer

0개의 댓글