[React 공식문서 공부하기] - JSX 소개

Lee Jeong Min·2021년 12월 30일
0
post-thumbnail

리액트 공식문서 주요개념 부분에 JSX 소개를 읽고 정리한 글입니다.

React에는 아래와 같은 희한한 문법을 볼 수 있다.

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

이는 문자열도 HTML도 아니고, JSX라 하며 JS를 확장한 문법이다. JSX라고 하면 템플릿 언어가 떠오를 수도 있지만, JS의 모든 기능이 포함되어 있다.

JSX는 React "엘리먼트"를 생성한다.

JSX란?

React에서는 본질적으로 렌더링 로직이 UI로직(이벤트가 처리되는 방식, 시간에 따라 state가 변하는 방식, 화면에 표시하기 위해 데이터가 준비되는 방식 등)과 연결된다는 사실을 전제한다.

React는 별도의 파일에 마크업과 로직을 분리하는 대신, '컴포넌트'라고 부르는 유닛으로 관심사를 분리한다.

React는 JSX 사용이 필수가 아니지만, 대부분의 사람은 JS 코드 안에서 UI 관련 작업을 할 때 시각적으로 더 도움이 된다고 생각한다.

JSX 없이 사용하는 React

React 사용 시, JSX는 필수가 아니다. 단지 JSX는 React 엘리먼트를 생성하는 React.createElement(component, props, ...children)을 호출하기 위한 문법적 설탕이다.

아래의 코드를 보자.

jsx 사용 코드

class Hello extends React.Component {
  render() {
    return <div>Hello {this.props.toWhat}</div>;
  }
}

ReactDOM.render(
  <Hello toWhat="World" />,
  document.getElementById('root')
)

jsx 사용 안한 코드

class Hello extends React.Component {
  render() {
    return React.createElement('div', null, `Hello ${this.props.toWhat}`);
  }
}

ReactDOM.render(
  React.createElement(Hello, {toWhat: 'World'}, null),
  document.getElementById('root')
);

컴포넌트는 문자열이나 React.Component의 하위 클래스 또는 컴포넌트를 위한 일반 함수로 제공된다.

함수형 컴포넌트, 클래스형 컴포넌트를 말하는 듯

React.createElement를 다음과 같이 줄여서 사용할 수도 있다.

const h = React.createElement;

ReactDOM.render(
  h('div', null, 'Hello World'),
  document.getElementById('root')
);

JSX에 표현식 포함하기

const name = 'JeongMin Lee';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);

이 예시에는 name이라는 변수를 선언한 후 중괄호로 감싸 JSX안에 사용

JSX의 중괄호 안에는 유효한 모든 JS 표현식을 넣을 수 있다.

문이아닌 표현식이라는 점에 유의하자.

아래 예시에서는 JS함수 호출의 결과인 formatName(user)라는 표현식의 값을 <h1> 엘리먼트에 포함한다.

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'JeongMin',
  lastName: 'Lee'
}

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);

ReactDOM.render(
  element,
  document.getElementById('root')
)

위와 같이 element의 JSX를 여러 줄로 나눌때, 자동 세미콜론 삽입을 피하기 위해 괄호를 묶는것을 권장한다.

JSX도 표현식이다

컴파일이 종료되면, JSX 표현식이 정규 JS 함수 호출이 되고 JS 객체로 인식된다.

즉, JSX를 if 구문 및 for loop 안에 사용하고, 변수에 할당하고, 인자로서 받아들이고, 함수로부터 반환할 수 있다.

const getGreeting = user => {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

JSX 속성 정의

어트리뷰트에 따옴표를 이용해 문자열 리터럴을 정의할 수 있다.

const element = <div tabIndex="0"></div>;

중과호를 사용해 어트리뷰트에 JS 표현식을 삽입할 수도 있다.

const element = <img src={user.avatarUrl}></img>;

어트리뷰트에 JS표현식을 삽입할 때 중괄호 주변에 따옴표를 입력하지 말고, 따옴표 또는 중괄호 중 하나만 사용하고 동일한 어트리뷰트에 두 가지를 동시에 사용하면 안된다.

JSX는 HTML보다 JS에 가까워서 ReactDOM은 HTML 어트리뷰트 이름 대신 camelCase 프로퍼티명 규칙을 사용한다.
class => className, tabindex => tabIndex

JSX로 자식 정의

태그가 비어있다면(자식이 비어있다면) XML 처럼 />를 이용해 바로 닫아 주어야한다.

const element = <img src={user.avatarUrl} />;

// 자식 포함할 때
const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

JSX는 주입 공격을 방지한다.

JSX에 사용자 입력을 삽입하는 것은 안전하다.

const title = response.potentiallyMaliciousInput;
const element = <h1>{title}</h1>;

기본적으로 ReactDOM은 JSX에 삽입된 모든 값을 렌더링하기 전, 이스케이프 처리를 한다.(<&lt로 바꾸는 것과 같은 작업) 또한 모든 항목은 렌더링 되기 전에 문자열로 변환된다. 이러한 특성으로 XSS 공격을 방지할 수 있다.

JSX는 객체를 표현한다.

Babel은 JSX를 React.createElement() 로 컴파일 시킨다. 따라서 아래의 코드가 다음과 같이 변환된다.

// JSX 문법
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

// Babel 사용 후 JSX => React.createElement 문법
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React.createElement()는 버그가 없는 코드를 작성하는데 도움이 되도록 몇 가지 검사를 수행하여 기본적으로 다음과 같은 객체를 생성한다.

const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

공식문서에선 이 예제로 사용된 객체는 단순화된 구조라고 설명한다.

이러한 객체를 React 엘리먼트라고 하며, 화면에서 보고 싶은 것을 나타내는 표현이고, React는 이 객체를 읽어서 DOM을 구성하고 최신 상태로 유지하는데 사용한다.

참고사이트

https://ko.reactjs.org/docs/introducing-jsx.html

profile
It is possible for ordinary people to choose to be extraordinary.

0개의 댓글