React 条件付きレンダリング

ReactBeginner
オンラインで実践に進む

はじめに

React における条件付きレンダリングは、特定の条件やアプリケーションの状態に基づいて異なるコンポーネントや要素を表示することを可能にするコアコンセプトです。これは、動的で応答性の高いユーザーインターフェースを構築するために不可欠です。例えば、ゲストユーザーには「ログイン」ボタンを表示し、ログイン中のユーザーには「プロフィール」ページを表示したい場合があります。

この実験 (Lab) では、React アプリケーションで条件付きレンダリングを実装するためのいくつかの一般的なテクニックを学びます。基本的なプロジェクトセットアップから始め、以下のさまざまな方法を段階的に探求します。

  • シンプルな if-else ロジックのための三項演算子 (? :)。
  • 条件が true の場合にのみ要素をレンダリングするための論理 && 演算子。
  • よりクリーンな JSX のために要素を格納する変数を使用すること。
  • コンポーネントのレンダリングを防ぐために null を返すこと。
  • React の状態を使用して、表示されるものを変更するインタラクティブな UI を作成すること。

この実験 (Lab) の終わりには、アプリケーションの状態に基づいてユーザーに何を表示するかを制御する方法について、確かな理解が得られるでしょう。

JSX で条件に三項演算子を使用する

このステップでは、JSX 内で直接インラインの if-else ロジックに条件付き(三項)演算子 (? :) を使用する方法を学びます。これは、レンダリングする 2 つの異なる UI 要素を切り替えるための簡潔な方法です。

まず、プロジェクトディレクトリに移動しましょう。すべてのコマンドはこのディレクトリから実行する必要があります。

cd ~/project/my-app

次に、プロジェクトの依存関係をインストールする必要があります。

npm install

それでは、メインアプリケーションコンポーネントを変更しましょう。左側のファイルエクスプローラーで src/App.jsx ファイルを開きます。ユーザーがログインしているかどうかに応じて異なるメッセージを表示する Greeting コンポーネントを作成します。

src/App.jsx の内容全体を以下のコードに置き換えてください。

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  return (
    <div>{isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}</div>
  );
}

function App() {
  return (
    <div>
      {/* isLoggedIn を false に変更して、別のメッセージを表示してみてください! */}
      <Greeting isLoggedIn={true} />
    </div>
  );
}

export default App;

Greeting コンポーネントでは、式 {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>} が isLoggedIn プロップの値を確認します。true の場合は、「Welcome back!」とレンダリングします。それ以外の場合は、「Please sign up.」とレンダリングします。

それでは、開発サーバーを起動して、コンポーネントが動作しているのを確認しましょう。

npm run dev -- --host 0.0.0.0 --port 8080

サーバーが起動したら、画面上部の Web 8080 タブを開きます。「Welcome back!」というメッセージが表示されるはずです。src/App.jsx で isLoggedIn={true} を isLoggedIn={false} に変更し、ファイルを保存して、ブラウザでコンテンツが自動的に更新されるのを確認してみてください。

短絡評価のために論理 AND 演算子 (&&) を適用する

このステップでは、条件付きレンダリングのもう一つの一般的なパターンである論理 && 演算子を探求します。これは、特定の条件が true の場合にのみ要素をレンダリングし、それ以外の場合は何もレンダリングしない場合に特に役立ちます。JavaScript では、true && expression は常に expression に評価され、false && expression は常に false に評価されます。React は false を何もレンダリングしない値として扱います。

これを実証するために、src/App.jsx ファイルを変更しましょう。未読メッセージがある場合にのみ通知数を表示するコンポーネントを追加します。

開発サーバーは実行したままにしてください。変更を確認するには、ファイルを編集して保存するだけで十分です。

src/App.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>
  );
}

function App() {
  const messages = ["React", "Re: React", "Re:Re: React"];
  // messages を空の配列に変更してみてください:const messages = [];
  return <Mailbox unreadMessages={messages} />;
}

export default App;

この例では、unreadMessages.length > 0 が true であるため、<h2> 要素がレンダリングされています。App コンポーネントで messages 配列を空 (const messages = [];) に変更すると、条件は false になり、<h2> 要素はレンダリングされなくなります。

ファイルを保存した後、Web 8080 タブを確認してください。「You have 3 unread messages.」というメッセージが表示されるはずです。

条件を変数に格納し、true の場合にレンダリングする

このステップでは、return ステートメントの前に変数でコンテンツを準備することにより、コンポーネントをよりきれいに保つ方法を学びます。このアプローチは、条件付きロジックが三項演算子や && ではうまく処理できないほど複雑になった場合に非常に役立ちます。

変数を使用することで、標準的な JavaScript の if ステートメントを使用して、コンポーネントが何をレンダリングすべきかを決定できます。

このテクニックを使用するために src/App.jsx を更新しましょう。プロップに基づいて「Login」または「Logout」ボタンのいずれかを表示するコンポーネントを作成します。

src/App.jsx の内容を以下のコードに置き換えてください。

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

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

function LoginControl(props) {
  const isLoggedIn = props.isLoggedIn;
  let button;

  if (isLoggedIn) {
    button = <LogoutButton />;
  } else {
    button = <LoginButton />;
  }

  return (
    <div>
      The user is <b>{isLoggedIn ? "currently" : "not"}</b> logged in.
      {button}
    </div>
  );
}

function App() {
  return <LoginControl isLoggedIn={false} />;
}

export default App;

LoginControl コンポーネントでは、button という変数を宣言します。次に、if ステートメントが <LoginButton /> または <LogoutButton /> のいずれかをそれに割り当てます。最後に、return ステートメントの JSX は単に {button} を含みます。これにより、レンダリングロジックが分離され、return ステートメントが読みやすくなります。

ファイルを保存し、Web 8080 タブで変更を確認してください。「Login」ボタンが表示されるはずです。isLoggedIn={false} を isLoggedIn={true} に変更して、「Logout」ボタンが表示されるのを確認してみてください。

false の場合は null または空のフラグメントをレンダリングする

このステップでは、コンポーネントがまったくレンダリングされないようにしたいシナリオをカバーします。これは、コンポーネントが null または空のフラグメント (<></>) を返すことで実現できます。

これは、特定の条件下でのみ表示されるべきコンポーネントの一般的なパターンです。例えば、実際に警告がある場合にのみ表示される警告バナーなどです。

src/App.jsx を変更して、warn プロップが true の場合にのみレンダリングされる WarningBanner コンポーネントを含めましょう。

src/App.jsx の内容を以下のコードに置き換えてください。

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

  return (
    <div style={{ backgroundColor: "yellow", padding: "10px", color: "black" }}>
      Warning!
    </div>
  );
}

function App() {
  // バナーを非表示にするには、これを false に変更してみてください
  const showWarning = true;

  return (
    <div>
      <WarningBanner warn={showWarning} />
      <p>This is the main content of the page.</p>
    </div>
  );
}

export default App;

WarningBanner コンポーネントでは、最初に warn プロップをチェックします。それが false の場合、コンポーネントはすぐに null を返し、React は何もレンダリングしません。それが true の場合、警告の div を返します。

ファイルを保存した後、Web 8080 タブを確認してください。黄色の警告バナーが表示されるはずです。次に、src/App.jsx に戻り、const showWarning = true; を const showWarning = false; に変更して保存してください。バナーがページから消えます。

状態を切り替えて条件付き表示を変更する

この最終ステップでは、条件付きレンダリングと React の状態を組み合わせて、インタラクティブなコンポーネントを作成します。これまでの条件はプロップに基づいています。状態を使用することで、ボタンをクリックするなどのユーザーのアクションに応答して、コンポーネントの出力が変化するようにすることができます。

コンポーネントの状態を管理するために useState フックを使用します。

src/App.jsx を変更して、独自の isLoggedIn 状態を管理し、ユーザーがそれを切り替えられるようにする LoginControl コンポーネントを構築しましょう。

まず、React から useState をインポートする必要があります。src/App.jsx の内容を以下のコードに置き換えてください。

import { useState } from "react";

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign up.</h1>;
}

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

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

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  const handleLoginClick = () => {
    setIsLoggedIn(true);
  };

  const handleLogoutClick = () => {
    setIsLoggedIn(false);
  };

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

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

export default App;

以下がその内容です。

  1. import { useState } from 'react'; は useState フックをインポートします。
  2. const [isLoggedIn, setIsLoggedIn] = useState(false); は状態変数 isLoggedIn を false で初期化します。setIsLoggedIn はこの状態を更新するために使用する関数です。
  3. 状態を更新するために setIsLoggedIn を呼び出す handleLoginClick および handleLogoutClick 関数を定義します。
  4. LoginButton および LogoutButton には、適切なハンドラー関数が onClick プロップ経由で渡されます。
  5. Greeting コンポーネントと button 変数は両方とも isLoggedIn 状態に依存しているため、状態が変更されるたびに再レンダリングされます。

ファイルを保存して、Web 8080 タブに移動してください。「Please sign up.」というメッセージと「Login」ボタンが表示されるはずです。「Login」ボタンをクリックしてください。状態が更新され、UI が「Welcome back!」と「Logout」ボタンを表示するように変化します。

まとめ

React の条件付きレンダリングに関するこの実験を完了したこと、おめでとうございます!さまざまな条件に基づいてアプリケーションが表示するものを制御するための、最も一般的なテクニックを学び、実践しました。

この実験では、以下の項目をカバーしました。

  • 三項演算子 (? :) を使用した、シンプルなインラインの if-else ロジック。
  • 論理 && 演算子 を適用して、条件が満たされた場合にのみ要素をレンダリングする。
  • JSX を変数に格納して、if ステートメントでより複雑なロジックを処理し、return ステートメントをきれいに保つ。
  • コンポーネントから null を返して、何もレンダリングされないようにする。
  • これらのテクニックを useState フックと組み合わせて、ユーザーのアクションに応答する動的でインタラクティブなユーザーインターフェースを作成する。

これらのパターンは、ほぼすべての React アプリケーションの基本的な構成要素です。これらを習得することで、豊かで応答性が高く、ユーザーフレンドリーなエクスペリエンスを作成できるようになります。