+ 알아야 할 것

createElement와 JSX와의 관계

JSX 문법

JSX expression

babel의 역할

+ 실습

createElement 함수로 만든 React Element를 JSX 문법을 사용해서 바꿔보기

JSX 문법

React element는 실제 DOM이 아닌 자바스크립트 객체라는 것을 확인하였지만 이렇게 Element를 생성하는것은 너무 번거롭다. 그래서 JSX 문법이 만들어졌고 문법이 훨씬 간소화가 되었다.

createElement() => JSX로의 변화 및 JSX 규칙

  1. 첫번째 파라메터 => 태그명으로 변경
  2. 두번째 파라메터 => 태그의 속성명으로 변경
  3. 세번째 이후 파라메터 => 모두 자식 노드로 변경
  4. class => className, for => htmlFor 의 속성명 으로  변경
  5. javascript expression => {} 를 사용
  6. 반드시 닫는 태그가 있어야 한다.

먼저 앞에서 createElement() API로 작성한 title을 JSX로 수정하면 다음과 같다.

  1. 첫번째 파라메터 h1 => <h1></h1>
  2. 두번째 파라메터 null => 해당없음
  3. 세번째 파라메터 => 자식 노드로 변환
const title = <h1 title="This is a title">My Scoreboard</h1>;
console.log(title);

const totalScore = <span>Total Score: 0</span>;

const players = <span>players: 0</span>;

const header = React.createElement(
  'div',
  { class: 'header d-flex justify-content-between align-items-center p-2'},
  totalScore, title, players
);

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

그러나, JSX 로 변환후에 실행해보면 Unexpected token < 에러가 발생한다. JSX 문법을 제대로 컴파일이 되지 않았다. index.html에 babel 스크립트를 추가하고 app.js에 type을 아래와 같이 추가한다.

<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel" src="./app.js"></script>

title이 콘솔창에 찍힌걸 보면 createElement로 생성한것과 동일한 것을 알수 있다. JSX는 React Elements를 생성하는 자바스크립트 문법이라는것을 알 수 있으며 그 생김새가 html 문법을 닮았기 때문에 사용하기가 더 편하다는 것 뿐이다. online babel 사이트에서 위 코드를  붙여 넣어보고 어떻게 컴파일되는지 살펴보자. https://babeljs.io 사이트에서 try it out 탭을 클릭하고 어떻게 변환되었는지 보자.

header 부분도 JSX 로 변환해보자. 두 줄 이상인 경우는 ()로 감싸는게 가독성을 위해서 좋다. 물론 () 가 없다고 틀린 문법은 아니다.

이미 만들어 놓은 세개의 자바스크립트 변수가 있으므로 jsx expresstion을 사용해서 배열에 3개의 변수를 넣어준다.

const title = <h1 title="This is a title">My Scoreboard</h1>;
console.log(title);

const totalScore = <span>Total Score: 0</span>;

const players = <span>players: 0</span>;

const header = (<div className="header d-flex justify-content-between align-items-center p-2">
  {[totalScore, title, players]}
</div>);

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

그러나, 자식 노드가 있는 경우는 변수를 만들기 보다 부모 아래 바로 자식 노드를 jsx로 만드는게 일반적이다. 

const header = (<div className="header d-flex justify-content-between align-items-center p-2">
  <span>Total Score: 0</span>
  <h1 title="This is a title">My Scoreboard</h1>
  <span>players: 0</span>
</div>);

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

JSX expression

JSX를 좀 더 동적으로 만들기 위해서는 태그 내부에 자바스크립트 변수를 {} 로 감싸서 삽입할 수 있다. 이것을 JSX expression 이라고 한다.

위 코드에서 title 을 자바스크립트 변수로 정의하면 다음과 같다.

const strTitle = 'This is a title';

const header = (<div className="header d-flex justify-content-between align-items-center p-2">
  <span>Total Score: 0</span>
  <h1 title={strTitle}>My Scoreboard</h1>
  <span>players: 0</span>
</div>);

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

id 부분에 자바스크립트 변수가 들어갔기 때문에 따옴표가 없다. 그리고 camel-case 규칙을 사용한다. class의 경우는 className이라는 camel-case를 사용해야 한다. 자바스크립트 변수가 아닌경우는 따옴표로 감싸서 스트링이라는것을 명시한다.

또한 class 대신에 className이 사용되었다. class는 이미 es6 예약어이기 때문에 className으로 사용해야 하고, 마찬가지로 label에 사용되는 for도 이미 예약된 다른 기능이 있기 때문에 htmlFor로 바꿔서 사용해야 한다.

JSX 내부에 주석을 추가하기 위해서 webstorm 단축키은 contrl-slash 로 한 줄을 주석처리해보자. {/* */} 로 감싸는것을 알 수 있다

+ quiz