본문 바로가기
programming_kr/react

조건부 렌더링

by JSsunday 2021. 1. 21.
728x90

 

React의 조건부 렌더링은 자바스크립트에서 동작하는 것과 동일하게 동작합니다. 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')
);

 

이 예제는 isLoggedIn prop의 값에 따라 다른 인사를 노출시킵니다.

 

요소 변수

 

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

 

로그아웃과 로그인 버튼을 나타내는 두개의 새 컴포넌트를 살펴봅시다.

 

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 = null;
    //LoginButton, LogoutButton는 위에 정의되어 있음.
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
      	{/*Greeting 컴포넌트는 위에 정의되어 있음.*/}
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

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

 

변수를 선언하고 if문을 사용하는 것은 조건부로 컴포넌트를 렌더링하는 훌륭한 방법이지만, 원한다면 더 짧은 구문을 사용할 수도 있습니다. JSX에 조건을 인라인으로 넣는 몇가지 방법을 소개합니다.

 

논리 && 연산자가 있는 인라인 조건

 

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

 

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      //unreadMessages.length가 0보다 크면 <h2>...</h2> 입력
      {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')
);

 

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

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

 

조건부 연산자를 사용한 인라인 If-Else

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

 

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {/*isLoggedIn이 true면 currently, false면 not*/}
      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>
  );
}

 

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

 

컴포넌트가 렌더링 되지 못하도록 방지

 

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

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

 

function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }
  //return null이기 때문에 다음 코드 return는 실행 안됨. 렌더링 되지 않음.

  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(prevState => ({
      showWarning: !prevState.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')
);

 

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

 

조건부 렌더링

 

728x90

'programming_kr > react' 카테고리의 다른 글

  (0) 2021.01.27
리스트와 키  (0) 2021.01.24
이벤트 제어  (0) 2021.01.19
state와 lifecycle  (0) 2021.01.16
컴포넌트와 props  (0) 2021.01.13

댓글