React での展開/折りたたみ機能の段階的な実装

Irakli Tchigladze 2023年6月21日
  1. React に展開/折りたたみ機能を実装する
  2. React でコンテナ全体を展開/折りたたむ
  3. React で特定の投稿を展開/折りたたむ
  4. React ですべての投稿を展開または折りたたむ
  5. まとめ
React での展開/折りたたみ機能の段階的な実装

Web アプリケーションを構築する場合、DOM 内の特定の要素の外観を動的に変更する必要があることがよくあります。

また、ユーザーが見たいときにだけコンテンツを表示する必要がある場合もあります。 これにより、ユーザーを圧倒することなく大量のコンテンツを管理し、優れたユーザー エクスペリエンスを提供できます。

この記事では、ユーザーによるボタンのクリックに応じてコンテナーを表示または非表示にする展開/折りたたみ機能を実装する方法を紹介したいと思います。

React に展開/折りたたみ機能を実装する

React では、条件付きでコンポーネントを非表示および表示できます。 コンポーネントがレンダリングされるかどうかは、ユーザーのアクションに応じて変更できる状態変数の値に依存します。

boolean 型の状態変数を格納できます。 JSX では、三項演算子 (または関数内で if 条件を使用) を使用して、特定の DOM 要素 (またはコンポーネント) をレンダリングするかどうかを条件付きで決定できます。

例を見てみましょう: <Post> コンポーネントによってレンダリングされた投稿のリストを表示する 1つの親コンポーネントがあります。

import "./styles.css";
import { useState } from "react";
export default function App() {
  let postsArr = ["post1", "post2", "post3", "post4", "post5"];
  const [postDisplay, setPostDisplay] = useState({
    post1: true,
    post2: true,
    post3: true,
    post4: true,
    post5: true
  });
  const [divDisplay, setDivDisplay] = useState(true);
  const handleClick = (post) => {
    const objectCopy = {
      ...postDisplay
    };
    objectCopy[post] = !objectCopy[post];
    setPostDisplay(objectCopy);
  };
  return (
    <div className="App">
      <button
        onClick={() =>
          setPostDisplay({
            post1: false,
            post2: false,
            post3: false,
            post4: false,
            post5: false
          })
        }
      >
        Hide All Posts
      </button>
      <br />
      <button
        onClick={() =>
          setPostDisplay({
            post1: true,
            post2: true,
            post3: true,
            post4: true,
            post5: true
          })
        }
      >
        Show All Posts
      </button>
      <br />
      <button onClick={() => setDivDisplay(!divDisplay)}>
        Expand/Collapse the post section
      </button>
      {postsArr.map((post) =>
        divDisplay ? (
          <div>
            <button onClick={() => handleClick(post)}>Expand {post}</button>
            {postDisplay[post] ? <Post key={post}></Post> : null}
          </div>
        ) : null
      )}
    </div>
  );
}

function Post() {
  return (
    <div className="post">
      <p>
        Some content
      </p>
    </div>
  );
}

この場合、1つの boolean 状態変数を持つ代わりに、boolean 値のオブジェクトが各投稿に 1つあります。 これにより、一部の投稿のみを展開し、他の投稿を折りたたむ (非表示にする) ことができます。

このコードを簡単に分析する前に、CodeSandbox で 動的展開/折りたたみ機能を確認できます。

App コンポーネント内には、投稿の配列があります。 JSX では、postsArr 配列に .map() メソッドを適用し、投稿のコンテナ全体または個々の投稿を表示するかどうかを条件付きでチェックします。

let postsArr = ["post1", "post2", "post3", "post4", "post5"];
...
{postsArr.map((post) =>
        divDisplay ? (
          <div>
            <button onClick={() => handleClick(post)}>Expand {post}</button>
            {postDisplay[post] ? <Post key={post}></Post> : null}
          </div>
        ) : null
)}

React でコンテナ全体を展開/折りたたむ

まず、divDisplay の値をチェックして、<Post /> コンポーネントを含む <div> 要素をレンダリングする必要があるかどうかを判断します。 CodeSandbox ライブ デモ にアクセスすると、ボタンがあることがわかります。

このボタンをクリックすると、divDisplay 状態変数の現在の値が反転します。 <div> コンテナが折りたたまれている場合、このボタンをクリックするとコンテナが展開されます。

展開されている場合、ボタンをクリックするとコンテナーが非表示になります。 このボタンのコードを見てみましょう。

<button onClick={() => setDivDisplay(!divDisplay)}>
        Expand/Collapse the post section
</button>

<button> 要素に onClick 属性を設定し、その値を setDivDisplay() 関数を呼び出す単純な矢印関数に設定して、divDisplay 状態変数を更新します。 useState フックを使用して updater 関数を定義しました。

const [divDisplay, setDivDisplay] = useState(true);

divDisplay 変数の値をデフォルトで true に設定します。 後で、ユーザーはボタンをクリックして、この変数の値を反転できます。

React で特定の投稿を展開/折りたたむ

投稿を含む <div> 要素全体を展開すると仮定すると、投稿のコンテンツを非表示または表示する個々の投稿を展開または折りたたむこともできます。

<Post> コンポーネントを生成するコード セクションを見てみましょう。

{postsArr.map((post) =>
        divDisplay ? (
          <div>
            <button onClick={() => handleClick(post)}>Expand {post}</button>
            {postDisplay[post] ? <Post key={post}></Post> : null}
          </div>
        ) : null
)}

postsArr 配列に map() メソッドを適用し、ボタンを表示/非表示にするボタンを格納する <div> 要素と、プロパティの postDisplay オブジェクトの値をチェックする三項演算子を返します。 配列内の各アイテムの。

ややこしいかもしれませんが、配列変数と状態変数をもう一度見てみましょう。

let postsArr = ["post1", "post2", "post3", "post4", "post5"];

const [postDisplay, setPostDisplay] = useState({
    post1: true,
    post2: true,
    post3: true,
    post4: true,
    post5: true
  });

ご存知かもしれませんが、map() メソッドは配列内の各文字列を取得します。 次に、postDisplay オブジェクトでこのプロパティの値をチェックします。

たとえば、最初の map() メソッドは 'post1' 文字列を受け取り、postDisplay['post1'] 式の値をチェックして <Post> コンポーネントをレンダリングします。

{postDisplay[post] ? <Post key={post}></Post> : null}

map() メソッドはコールバック関数を引数として取り、各配列項目を変数として扱うことに注意してください。 したがって、ブラケット表記を使用してプロパティの値を検索する必要があります。

プロパティ値が false の場合、三項演算子は null を返し、何もレンダリングしません。

CodeSandbox デモ に移動し、ボタンをクリックして個々の投稿を展開したり折りたたんだりしてみてください。 オブジェクト形式を使用すると、一部の投稿のコンテンツを展開しながら、他の投稿を折りたたむことができます。

React ですべての投稿を展開または折りたたむ

ページの上部には 2つのボタンがあります。1つ目は現在展開されている可能性のあるすべての投稿を折りたたみ、2つ目はすべての投稿を展開します。 ライブデモでこれらのボタンをクリックして、機能をよりよく理解してください。

それでは、これが React 内でどのように達成されるかを見てみましょう。

<button
	onClick={() =>
	  setPostDisplay({
		post1: false,
		post2: false,
		post3: false,
		post4: false,
		post5: false
	  })
	}
  >
	Hide All Posts
  </button>
  <br />
  <button
	onClick={() =>
	  setPostDisplay({
		post1: true,
		post2: true,
		post3: true,
		post4: true,
		post5: true
	  })
	}
  >
	Show All Posts
  </button>

onClick 属性を設定するので、ユーザーが最初のボタンをクリックするたびに、すべてのプロパティ (個々の投稿のステータスに対応) の値が false に設定されているオブジェクトで setPostDisplay() 関数を呼び出します。 .

2 番目のボタンも同じですが、この場合はすべてのオブジェクト プロパティが true に設定されています。 したがって、これらのボタンをクリックすると、すべての投稿のコンテンツが展開されます。

まとめ

これは非常に単純な例です。 通常、Web サイトには、React でコンテナーを展開および折りたたむためのよりスタイリッシュなボタンがあります。 ボタンのスタイルは異なる場合がありますが、機能の実装はここで示したものと同じか、非常に似ています。

Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn