조건부 렌더링(Conditional Rendering)

React Component는 스스로 State를 통해서 화면을 나타내며, 이러한 React Component를 조합하여 복잡한 UI를 생성할 수 있습니다. 복잡한 UI를 생성하기 위해서는 React Component는 로직을 사용할 수 있어야 하며, 로직에 따른 UI를 화면에 나타낼 것입니다. 먼저 우리는 화면에 UI요소들을 나타내기위한 JSX templet 문법 을 먼저 다룰 줄 알아야 합니다.

1.JSX

JSX문법은 JavaScript의 확장된 문법으로써 얼핏보면 HTML과 비슷한 형태로 작성되는 것 처럼 보입니다. JSX는 JavaScript의 확장된 문법이기 때문에, React에서의 Templet언어로써 사용되며 JavaScript의 모든 기능을 제공합니다. 예시를 먼저 살펴보겠습니다.

  • JSX를 사용하지않은 React Element
const element = React.createElement(
  "div", null, React.createElement(
    "a", null, "Hello JSX with BABEL!", ""
  )
);
  • JSX문법을 이용한 React Element
const element = (
  <div>
    <a> { "Hello JSX with BABEL!" } </a>
  </div>
);

위의 두 종류의 코드는 같은 결과값을 가지게 됩니다. 짧은 코드이지만, 잠깐만 살펴보아도 첫 번째의 예제 코드보다 두 번째의 예제 코드가 훨씬 가독성이 좋다는 것을 확인할 수 있습니다. 또한 JSX문법 안에서 { } 안의 코드는 모두 JavaScript문법으로 인식되기 때문에 위의 <a> { "Hello JSX with BABEL" } </a> 에서 JavaScript의 표현식을 사용할 수 있었습니다.

물론 React에서 JSX문법은 필수요소가 아닙니다. 하지만 JSX문법은 React에서 편리성을 제공해줍니다.

1-1. BABEL

위의 예시에서 확인해본 JSX문법은 그자체로는 사용할 수 없습니다. JSX문법을 사용하기 위해서는 React를 import해주어야 합니다. import React from 'react' React에서 JSX문법은 React.createElement() 구문으로 변환됩니다. BEBEL 이라는 것을 통해서 변환이 됩니다. 위의 두 예제를 BABEL이 어떻게 변환해주는지 다시한번 확인해보겠습니다.


BABEL은 컴파일타임에 왼쪽의 JSX 태그들로 이루어진 JSX문법들을 오른쪽 React.createElement문법으로 변환해줍니다.( BABEL 공식홈페이지에서 확인할 수 있습니다. [https://babeljs.io/])

1-2 JSX 문법

  • 표현식을 이용하는 JSX 문법
  const name = 'JH Kim';
  const element = <div> `my name is ${name}` </div>;
  • 함수를 사용하는 JSX 문법
  function Introduce() {
    return (
      <div> `my name is ${name}` </div>
    )
  }
  • 함수형 컴포넌트에서의 JSX
  const Introduce = (props) => {
    return <div> `my name is ${props.name}` </div>
  }
  • 클래스형 컴포넌트에서의 JSX
  class Introduce extends React.Component {
    render() {
      return <div> `my name is ${this.props.name}` </div>
    }
  }
  • 여러개의 자식태그들을 포함한 JSX
  const Introduce = (props) => {
    return (
      <div>
        <h5>`Hello!`</h5>
        <h5>`my name is ${props.name}`</h5>
      </div>
    )
  }
  • 잘못된 문법
  const Introduce = (props) => {
    return (
      <h5>'Hello'</h5>
      <h5>`my name is ${props.name}`
    )
  }

JSX문법은 한번에 하나의 요소만 return할 수 있습니다. 또한 JSX태그를 이용한 후 반드시 닫는 태그를 사용해주어야 합니다.

const Introduce = (props) => {
  return (
    <div>
      <h5>'Hello'</h5>
      <h5>`my name is ${props.name}`</h5>
    </div>
  )
}

2. 조건부 렌더링

In React, you can create distinct components that encapsulate behavior you need. Then, you can render only some of them, depending on the state of your application.

React에서는 필요한 동작을 캡슐화하는 고유한 구성요소를 만들 수 있습니다. 그런 다음 응용프로그램의 상태에 따라 일부만 렌더링 할 수 있습니다.

-React 공식문서, 조건부 렌더링

2-1 3항연산자를 이용한 렌더링

  • 3항연산자를 사용하는 렌더링방식은 주로 조건에 맞는 엘리먼트와 조건에 맞지 않는 엘리먼트를 구분지어 렌더링할 때 사용합니다.
  const LoginedUser = (props) => {
    return <div> `Hi ${props.name} [User] Welcome to React!` </div>
  }

  const Guest = (props) => {
    return <div> `Hi ${props.name} [Guest] Welcome to React.` </div>
  }

  class MainPage extends React.Component {
    //
    render() {

      const { isLogined } = this.props;
      return (
        {
          isLogined
          ? <LoginedUser name={'JH Kim'} />
          : <Guest name={'CH Kim'} />
        }
      )
    }
  }

위의 코드에서는 props로 전달받은 isLogined에 따라서 true일 경우에는 LoginedUser 컴포넌트를 렌더링하고, false 일 경우에는 Guest 컴포넌트를 렌더링 합니다.

2-2 AND연산자를 이용한 렌더링

  • AND연산자를 이용한 렌더링방식은 조건에 맞지않는 엘리먼트는 제외하고 렌더링할 때 주로 사용하는 방식입니다.
  class UserInfo extends React.Component {
    //
    render() {

      const { user } = this.props;
      return (
        <form>
          <label>
            Id:
            <p> { user && `${user.id} `} </p>
          </label>
          <label>
            Name:
            <p> { user && `${user.name} `} </p>
          </label>
          <label>
            Age:
            <p> { user && `${user.age} `} </p>
          </label>
        </form>
      )
    }
  }

위의 코드에서는 props로 받은 user가 없다면 화면에 아무 값도 나타내지 않으며, user라는 객체가 props로 넘어왔다면 각각의 Id, Name, Age값을 화면에 나타내줍니다.

2-3 if문을 이용한 렌더링

  • 일반적으로 JSX문법 안에서 if문을 사용하기 위해서는 IIFE(즉시실행함수)를 사용해야합니다. 대부분의 상황에서는 위 두가지 방법으로 처리가 가능하지만 보다 복잡한 조건을 if문으로 작성해야 할 경우에 사용합니다. 또한 복잡한 조건은 JSX내부가 아닌 밖에서 로직을 따로 작성하는 방법이 더 좋습니다.
  class Grade extends React.Component {
    //
    render() {

      const { grade } = this.props;
      render() {
        return (
          () => {
            if(grade <= 50) return (<div> F </div>);
            if(grade > 50 && grade <= 60) return (<div> D </div>);
            if(grade > 60 && grade <= 70) return (<div> E </div>);
            if(grade > 70 && grade <= 80) return (<div> C </div>);
            if(grade > 80 && grade <= 90) return (<div> B </div>);
            if(grade > 90 && grade <= 100) return (<div> A </div>);
          }
        )
      }
    }
  }

마무리

여기까지 JSX문법의 사용법과 JSX문법을 사용한 선택적 렌더링에 대하여 알아보았습니다. JSX문법은 React Element를 좀더 편리하게 작성할 수 있게 도와주며 JavaScript 문법을 모두 포함하기 때문에 가독성이 좋고 좀더 효율적인 코드작성에 도움을 줍니다. 다음 글에서는 JSX문법과 선택적 렌더링을 사용하여 다양한 자료구조(List, Map, Tree)로 이루어진 데이터를 어떻게 화면에 나타내는지에 대하여 알아보겠습니다.