React_Docs : 조건부 렌더링

daymoon_·2022년 6월 2일
0

ReactDocs

목록 보기
6/11
post-thumbnail

조건부 렌더링

🔎 React 공식문서 자료
React_조건부 렌더링

React에서는 원하는 동작을 캡슐화하는 컴포넌트를 만들 수 있다. 이렇게 하면 애플리케이션의 상태에 따라서 컴포넌트 중 몇 개만을 렌더링할 수 있다.

📖 캡슐화??

  • 정보통신기술용어해설_캡슐화
  • wikipedia_캡슐화
  • 객체 지향 프로그래밍(OOP; Object-Oriented-Programming)의 특징
  • 데이터(변수) 및 함수(처리방법, 메소드)를 클래스로 묶는 작업
  • 임의의 객체 요소의 접근을 제한 ▶ 메소드나 프로퍼티 앞에 붙여 다른 객체에게 노출시키는 정도로써의 보호수준을 결정하는 제한자
  • 정보 은닉 : 내부 데이터를 캡슐화시켜 변경을 어렵게하고 보호함

React에서 조건부 렌더링은 JavaScript에서의 조건 처리와 같이 동작한다. if조건부 연산자와 같은 JavaScript 연산자를 현재 상태를 나타내는 에리먼트를 만드는 데에 사용해야 한다. 그러면 React는 현재 상태에 맞게 UI를 업데이트 한다.


⚙️ 예시 코드 - 1

  • props 값을 받아서 상황에 따라 바뀌는 컴포넌트 2개를 생성
function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

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

⚙️ 예시 코드 - 2

  • true : UserGreeting 컴포넌트 렌더링
  • false : GuestGreeting 컴포넌트 렌더링
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')
);

엘리먼트 변수

엘리먼트를 저장하기 위해 변수를 사용할 수 있다. 출력의 다른 부분은 변하지 않은 채로 컴포넌트의 일부를 조건부로 렌더링할 수 있다.

⚙️ 예시 코드 - 1

  • 로그아웃을 나타내는 LogoutButton 컴포넌트
  • 로그인을 나타내는 LoginButton 컴포넌트
function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

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

⚙️ 예시 코드 - 2

  • 현재 상황에 따라 <LoginButton /> 혹은 <LogoutButton /> 컴포넌트로 렌더링
  • 이전 예시의 <Greeting /> 컴포넌트도 함께 렌더링
  • 변수를 선언하고 if를 사용해서 조건부로 렌더링
// ✨ 클래스형 컴포넌트 생성
class LoginControl extends React.Component {
  // 클래스 객체 생성 & 초기화
  constructor(props) {
    // 부모 클래스를 물려받음 (즉, 부모 클래스를 사용하기 위해 super 사용)
    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) {
      // true
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      // false
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

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

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

논리 && 연산자로 if를 인라인으로 표현하기

JSX 안에는 중괄호를 이용해서 표현식을 포함할 수 있다. 그 안에 JavaScript의 논리 연산자 &&를 사용하면 쉽게 엘리먼트를 조건부로 넣을 수 있다.

⚙️ 예시 코드 - 1

  • JavaScript에서 true && expression은 항상 expression으로 평가되고 false && expression은 항상 flase로 평가된다. 따라서 && 뒤의 엘리먼트는 조건이 true일 때 출력된다. 조건이 false라면 React는 무시하고 건너뛰게 된다.
  • true && expression
  • false && expression

⚙️ 예시 코드 - 2

  • falsy 표현식을 반환하면 여전히 && 뒤에 표현식은 건너뛰지만 falsy 표현식이 반환됨다는 것에 주의해야 한다.
  • 아래 코드는 <div>0</div>이 render 메서드에서 반환된다.
render() {
  const count = 0;
  return (
    // {0 && <h1>Messages: {count}</h1>}
    // 🛑 falsy값 0이 들어가면 falsy값을 반환!!
    <div>
      {count && <h1>Messages: {count}</h1>}
    </div>
  );
}

조건부 연산자로 if-else 구문 인라인으로 표현하기

엘리먼트를 조건부로 렌더링하는 다른 방법은 조건부 연산자인 condition ? true : false를 사용한다. (삼항 조건 연산자를 사용하자!)

⚙️ 예시 코드 - 1

  • 삼항 조건 연산자를 이용하면 다음과 같은 코드로 작성할 수 있다.
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    // true ▶ currently 반환
    // false ▶ not 반환
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}

⚙️ 예시 코드 - 2

  • 예시 코드 - 1보다 더 큰 표현식을 사용하면 다음과 같은 코드를 작성할 수 있다.
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    // true ▶ <LogoutButton onClick={this.handleLogoutClick} /> 반환
    // false ▶ <LoginButton onClick={this.handleLoginClick} /> 반환
    <div>
      {isLoggedIn
        ? <LogoutButton onClick={this.handleLogoutClick} />
        : <LoginButton onClick={this.handleLoginClick} />
      }
    </div>
  );
}

두 예시 코드 중에서 가독성이 좋다고 생각하는 것을 선택하면 된다. 즉, 본인의 취향이다. 만약 조건이 너무 복잡하다면 컴포넌트 분리를 사용하는 것이 효율적이다.


컴포넌트가 렌더링하는 것을 막기

가끔 다른 컴포넌트에 의해 렌더링될 때 컴포넌트 자체를 숨기고 싶을 때가 있다. 이때는 렌더링 결과를 출력하는 대신 null을 반환하면 된다.

⚙️ 예시 코드 - 1

  • <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')
);

컴포넌트의 render 메서드로부터 null을 반환하는 것은 생명주기 메서드 호출에 영향을 주지 않는다. 그 예로 componentDidUpdate는 계속해서 호출되게 된다.

profile
미지의 공간🌙

0개의 댓글