React JSX

JSX 란?

function App() {
  return (
    <div className="greeting">
      Hello <b>world!</b>
    </div>
  );
}

위의 태그 문법은 문자열도, HTML도 아닌 JSX라 하며 JavaScript를 확장한 문법이다.
JSX는 React 엘리먼트(element)를 생성한다.

이런 형식으로 작성한 코드는 브라우저에서 실행되기 전에 코드가 번들링(여러가지 파일을 모아서 하나로 만드는 것)되는 과정에서 Babel을 사용하여 아래 코드와 같은 일반 자바스크립트 형태의 코드로 변환된다.

function App() {
  return React.createElement(
    'div',
    { className: 'greeting' },
    'Hello ',
    React.createElement('b', null, 'world!')
  );
}

만약 컴포넌트를 렌더링할 때마다 위 코드처럼 매번 React.createElement 함수를 사용해야 한다면 매우 불편할 것이다. 이와 같은 불편함을 해소하기 위해 JSX를 사용하면 매우 편하게 코드를 작성할 수 있고 가독성도 좋아진다.

JSX 문법

  1. JSX는 HTML보다는 JavaScript에 가깝기 때문에, React DOM은 HTML Attribute 이름 대신 camelCase 프로퍼티 명명규칙을 사용한다.
    ex) class -> className, tabindex -> tabIndex

  2. 컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 한다.
function App() {
  return (
    <div>
      <h1>Hello</h1>
      <h2>world!</h2>
    </div>
  );
}

위 코드에서 h1h2 태그를 div 태그로 감싸지 않았다면 해당 코드는 제대로 작동하지 않을 것이다. 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문인데 이와 같이 리액트 컴포넌트에서 여러 개의 요소를 하나의 요소로 감싸는 이유는 Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 하기 위함이다.

꼭 div 요소를 사용하지 않고 아래와 같은 Fragment 형태로도 표현 가능하다.

function App() {
  return (
    <>
      <h1>Hello</h1>
      <h2>world!</h2>
    </>
  );
}
  1. 자바스크립트 표현식을 쓸 수 있다.
function App() {
  const name = 'daewoong!';
  return (
    <>
      <h1>Hello</h1>
      <h2>{name}</h2>
    </>
  );
}
  1. AND 연산자(&&)를 사용한 조건부 렌더링
function App() {
  const name = 'daewoong!';
  return (
    <>
      <h1>Hello</h1>
      <h2>{name}</h2>
      {name === 'daewoong' && <h3>admin</h3>}
    </>
  );
}

&& 연산자를 사용하여 특정 조건을 만족할 때 내용을 보여주고, 만족하지 않을 때 아무것도 렌더링하지 않을 수 있다.

  1. 컴포넌트에서 undefined만 반환하여 렌더링하면 안된다. 다음 코드는 오류가 발생한다.
function App() {
  const name = undefined;
  return name;
}

JSX 내부에서 undefined를 렌더링하는 것은 괜찮다.

function App() {
  const name = undefined;
  return <div>{name}</div>;
}

name 값이 undefined일 때 보여주고 싶은 문구가 있다면 다음과 같이 코드를 작성하면 된다.

function App() {
  const name = undefined;
  return <div>{name || 'daewoong'}</div>;
}
  1. 인라인 스타일링
function App() {
  const name = 'daewoong';
  const style = {
    color: 'blue',
    fontSize: '30px',
    margin: 5
  };
  return <div style={style}>{name}</div>;
}

리액트에서 DOM 요소에 스타일을 적용할 때는 문자열 형태로 넣는 것이 아니라 위 코드처럼 객체 형태로 넣어주어야 한다. 미리 선언하지 않고 바로 style을 지정하고 싶다면 다음과 같이 작성하면 된다.

function App() {
  const name = 'daewoong';
  return (
    <div
      style={{
        color: 'blue',
        fontSize: '30px',
        margin: 5
      }}
    >
      {name}
    </div>
  );
}
  1. JSX에서 CSS 클래스를 사용할 때는 class 대신 className으로 설정해준다.

  2. 태그를 꼭 닫는다. 태그 사이에 별도의 내용이 들어가지 않는 경우에는 self-closing 태그를 사용한다.
function App() {
  const name = 'daewoong';
  return (
    <>
      <div className="user_name">{name}</div>
      <input />
    </>
  );
}
  1. 주석
function App() {
  const name = 'daewoong';
  return (
    <>
      {/* 주석은 이렇게 작성한다. */}
      <div className="user_name">{name}</div>
    </>
  );
}

reference:

리액트 공식 문서