11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【JavaScript】React:条件付きレンダーって?

Last updated at Posted at 2019-07-31

https://ja.reactjs.org/docs/conditional-rendering.html
こちらを元に学習しています。

#レンダーの条件分岐やってみよう

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

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

この2つのコンポーネントを、以下のコードを加えてログイン状況によって一方だけ表示したいとします。

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

ReactDOM.render(
  // falseをtrueにかえると表示が変わる。
  <Greeting isLoggedIn={true} />,
  document.querySelector('body')
);

constで宣言したisLoggedInにpropsが代入されています。
それを元に条件分岐ですね。reactの良さが出てきた気がします。

上記の例ではpropsを利用したファンクションコンポーネントの場合だったので、
次はクラスで作成されたステート付きコンポーネントで条件分岐してみます。
先ほどのコードの続きから書いてください。

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

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

UseGreetingなどのコンポーネントと似ていますが、
イベントハンドラが設定されていて、propsによってその条件が分岐するようです。

そして以下のコードを追加します。

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

先ほどのGreetinコンポーネントもトグルさせています。
条件分岐はできましたが、なかなか長いコードになりましたね。

##もっと色々な条件分岐
###&&を使う

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

これは&&を使ったよくあるテクニックですね。&&の左の式が間違っていれば右の式は実行されないというやつです。
lengthがfalseではない→メッセージがある時のみ右の式が実行されて、条件分岐が成功しています。

###三項演算子を使う

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

isLoggedInがtrueならcurrentlyを、そうでなければnotを返します。
三項演算子は嫌われますが私は好きです。用量を守って利用したいですね。

##コンポーネントをレンダーさせない
レンダーさせたくないときは、出力にnullでオッケーです。

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

ただし、コンポーネントのライフサイクルはnullにしても発火するので注意です!

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?