[React] 리액트 JSX

JSX란 자바스크립트를 확장한 문법이다. 얼핏 보면 HTML과 비슷하여 템플릿 언어가 떠오를 수도 있지만, 자바스크립트의 모든 기능이 포함되어 있다. JSX를 제대로 사용하기 위해서 몇가지 규칙을 준수해줘야 한다. 이전 포스팅 [React] React 시작하기에 나온 App.js파일에 예제를 작성하여 진행하겠다. 기존의 코드는 지우고 클래스 방식으로 컴포넌트를 만들어준 뒤 아래 예제들을 살펴보겠다.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        
      </div>
    );
  }
}

export default App;

JSX 엘리먼트 규칙

태그는 꼭 닫혀줘야 된다.

<div>를 열었으면 꼭</div>로 태그를 닫아주도록 한다. 또한 input이나 br태그 같은 단일 태그들은 HTML5에서 안닫아도 상관 없었지만, 리액트에서는 오류를 출력하므로 꼭 태그를 닫아주도록 한다.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <input type="text"> // error
      </div>
    );
  }
}

export default App;

하나의 엘리먼트로 감싸줘야 한다.

리턴값이 두개의 엘리먼트로 되어있으면 오류를 출력한다.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div> // error
        my
      </div>
      <div>
        app
      </div>
    );
  }
}

export default App;

위 문제를 해결하기 위해서 두개의 엘리먼트를 하나의 엘리먼트로 감싸야 한다.

하나의 엘리먼트로 감싸기 까다로운 경우

하지만 위처럼 하나의 엘리먼트로 감싸기엔 까다로운 경우가 있다. CSS로 인한 스타일 관련 문제나 table관련 태그를 작성할 때 번거로운 경우이다. 이럴때는 아래처럼 Fragment을 사용하면 된다.(이 기능은 v.16.2에 도입되었다.)

import React, { Component, Fragment } from 'react';

class App extends Component {
  render() {
    return (
      <Fragment>
        <div>
          my
        </div>
        <div>
          app
        </div>
      </Fragment>
    );
  }
}

export default App;

나눠진 엘리먼트를 Fragment로 감싼뒤 import{ Component }Fragment을 추가하면 된다.

JSX 자바스크립트 사용하기

변수 사용하기

JSX 내부에서 변수를 사용 할 땐 아래처럼 할 수 있다.

import React, { Component } from 'react';

class App extends Component {
  render() {
    const name = 'my-app';
    console.log(1)
    return (
      <div>
        hello {name} // hello my-app
      </div>
    );
  }
}

export default App;

JSX 내부에 {}(중괄호)안에 자바스크립트 구문을 넣어 주면 된다.

조건부 렌더링

JSX 내부에서 조건부 렌더링을 할 때는 보통 삼항 연산자를 사용하거나, AND연산자(&&)를 사용한다. 반면에 if문은 사용할 수 없으며, 사용하려면 즉시함수를 실행해야 한다.

삼항연산자

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        {
          1 + 1 === 2 // 참
          ? <div></div>
          : <div>거짓</div>
        }
      </div>
    );
  }
}

export default App;

AND연산자

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        {
          1 + 1 === 2 // 참
          && <div></div>
        }
      </div>
    );
  }
}

export default App;

참고로 AND연산자의 경우 true일때만 값을 보여주고, false일때는 아무것도 보여주지 않는다.

if문

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        {
          (function(){
            if (1 + 1 === 2) { // 참
              return <div></div>
            } else {
              return <div>거짓</div>
            }
          })()
        }
      </div>
    );
  }
}

export default App;

위처럼 JSX 내부에서 로직을 작성할 수 있지만 복잡한 로직을 작성해야 할 때는 JSX 밖에서 로직을 작성하는 것이 좋다. 하지만 꼭 JSX 내부에서 작성해야 한다면 위처럼 즉시실행함수를 사용하면 된다.

style과 className

JSX에서 CSS와 class명은 HTML에서 작성하는 방법과 약간 다르다.

import React, { Component } from 'react';

class App extends Component {
  render() {
    const style = {
      padding: '10px',
      fontSize: '15px',
      fontWeight: 'bold',
      backgroundColor: 'yellow'
    };
    return (
      <div style={style}>
        my-app
      </div>
    );
  }
}

export default App;

HTML에서는 그냥 텍스트 형태로 ="padding: 10px; font-size: 15px;" 이런 형태로 작성하였다면 리액트에서는 객체 형태로 작성해줘야 한다. 그리고 class는 class대신에 className을 사용한다.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div className="App">
        my-app
      </div>
    );
  }
}

export default App;

주석

주석은 아래처럼 {/* 내용 */} 사이에 넣거나, 태그 사이에 넣을 수 있다.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        {/* 주석 내용 */}
        <div
        // 태그 사이에 주석 내용
        >my-app
        </div>
      </div>
    );
  }
}

export default App;

References

누구든지 하는 리액트 3편: JSX
JSX 소개

updated_at 07-03-2020