https://reactjs.org/docs/conditional-rendering.html - 번역 글

React에서는 필요한 동작을하는 캡슐화된 고유 한 컴포넌트를 만들 수 있습니다. 그런 다음 응용 프로그램의 state에 따라 일부만 렌더링 할 수 있습니다.

React의 조건부 렌더링은 JavaScript가 동작하는 것과 같은 방식으로 동작합니다. if 또는 조건 연산자와 같은 자바 스크립트 연산자를 사용하여 현재 state를 나타내는 요소를 만들고 React가 UI를 업데이트하여 일치 시킵니다.

두 컴포넌트를 살펴봅시다.

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

사용자의 로그인 여부에 따라 위 컴포넌트 중 하나를 표시하는 Greeting 컴포넌트를 만들었습니다.

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  // Try changing to isLoggedIn={true}:
  <Greeting isLoggedIn={false} />,
  document.getElementById('root')
);

CodePen

위 예제는 props isLoggedIn 값에 따라 다른 인사말 컴포넌트를 렌더링합니다 .


Element Variables(요소 변수)

변수를 사용하여 요소를 저장할 수 있습니다. 이렇게 하면 컴포넌트의 일부를 조건부로 렌더링하는 데 도움이 되며 나머지 출력은 변경되지 않습니다.

로그 아웃 및 로그인 버튼을 나타내는 다음 두 개의 새로운 컴포넌트를 살펴보겠습니다.

function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}

위 예제에서, LoginControl 이라는 state를 가진 컴포넌트 를 생성했습니다.

이 컴포넌트는 현재 상태에 따라 <LoginButton /> 혹은 <LogoutButton /> 중 하나를 렌더링 할 것입니다. 이전 예제에서 만들었던 <Greeting /> 도 렌더링합니다.

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;

    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

CodePen

변수를 선언하고 if문을 사용하는 것은 조건부로 구성 요소를 렌더링하는 좋은 방법이지만, 짧은 구문을 사용하고 싶은 경우가 있습니다. 아래에 예시로 JSX를 이용하여 인라인으로 조건을 처리하는 몇 가지 방법이 있습니다.

Inline If with Logical && Operator(논리 && 연산자가 있는 인라인 조건)

중괄호로 감싸면 JSX에 어떤 표현식이든 넣을 수 있습니다. 예제에서는 자바스크립트 논리 && 연산자도 포함됩니다. 이를 사용하면 요소의 조건부 포함을 더 편리하게 할 수 있습니다.

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('root')
);

CodePen

자바스크립트에서 true && expression 은 항상 expression 으로 평가되고, false && expression 은 항상 false 로 평가되기 때문에 이 코드는 동작합니다.

따라서 조건이 true 라면 && 다음에 오는 요소가 노출됩니다. 만약 조건이 false 라면, React는 이를 무시하고 건너뜁니다.

Inline If-Else with Conditional Operator(조건부 연산자를 사용한 인라인 If-Else)

인라인으로 요소를 조건부 렌더링하는 다른 방법은 자바스크립트의 조건부 연산자인 condition ? true : false 를 사용하는 것입니다.

아래 예제에서, 작은 텍스트 블록을 조건부로 렌더링합니다.

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}

또한 더 큰 표현을 위해 사용할 수도 있지만 덜 명백하게 보입니다.

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

자바스크립트에서와 마찬가지로 당신과 당신의 팀이 더 읽기 쉽다고 생각하는 것을 바탕으로 적절한 스타일을 선택하면 됩니다. 또한 조건이 너무 복잡해질 때마다 컴포넌트를 추출 하면 좋습니다.

Preventing Component from Rendering(컴포넌트가 렌더링 되지 못하도록 방지)

흔하지 않지만 컴포넌트가 다른 컴포넌트에 의해 렌더링 되었더라도 이를 숨길 수 있습니다. 이렇게 하려면 렌더 출력 대신 null 을 반환합니다.

아래 예제에서, <WarningBanner />warn prop의 값에 의존해 렌더링됩니다. 만약 prop 값이 false 라면, 이 컴포넌트는 렌더링되지 않습니다.

function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state => ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Page />,
  document.getElementById('root')
);

CodePen

컴포넌트의 render 메서드에서 null 을 반환하면 컴포넌트의 라이프사이클 메서드가 구동하지 않습니다. 대신, componentWillUpdatecomponentDidUpdate는 여전히 호출됩니다.