【初心者向け】ReactのuseStateフックとContext APIでコンポーネント間ステート共有をマスターしよう

2024-06-15

ReactにおけるuseStateフックとコンポーネント間ステート共有

コンポーネント間ステート共有には、主に以下の3つの方法があります。

それぞれの方法には一長一短があり、状況に応じて最適な方法を選択する必要があります。

useStateフックとContext APIを組み合わせることで、柔軟かつ効率的なステート共有を実現することもできます。

以下、それぞれの方法の例と、useStateフックとの使い分けについて詳しく説明します。

props渡し

例:

// 親コンポーネント
const Parent = () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <Child count={count} setCount={setCount} />
    </div>
  );
};

// 子コンポーネント
const Child = ({ count, setCount }) => {
  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>インクリメント</button>
    </div>
  );
};

説明:

  • 親コンポーネント Parent は、count というステートと、そのステートを更新するための関数 setCount を持っています。
  • 親コンポーネントは、Child コンポーネントに countsetCount をpropsとして渡します。
  • Child コンポーネントは、受け取った count を表示し、setCount を使ってボタンクリック時に count をインクリメントします。

useStateフックとの使い分け:

  • シンプルで理解しやすい
  • コンポーネント階層が浅い場合に適している
  • ステートの更新処理が単純な場合に適している

注意点:

  • コンポーネント階層が深くなると、props渡しによるコードが冗長になり、メンテナンスが難しくなる
  • 双方向データバインディングのように見えるが、実際は一方通行であることに注意が必要

Context API

// ステートコンテキストを作成
const CountContext = React.createContext({ count: 0, setCount: () => {} });

// 親コンポーネント
const Parent = () => {
  const [count, setCount] = useState(0);
  return (
    <CountContext.Provider value={{ count, setCount }}>
      <Child />
    </CountContext.Provider>
  );
};

// 子コンポーネント
const Child = () => {
  const { count, setCount } = React.useContext(CountContext);
  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>インクリメント</button>
    </div>
  );
};
  • CountContext というステートコンテキストを作成します。
  • 親コンポーネントは、CountContext.Provider を使ってステートコンテキストの値 (countsetCount) を子コンポーネントに提供します。
  • Child コンポーネントは、React.useContext フックを使ってステートコンテキストの値を取得します。
  • コードがスッキリし、ステート更新処理も容易
  • 複数階層のコンポーネント間でステートを共有する場合に適している
  • グローバルスコープに近い性質を持つため、誤った使い方



テーマコンテキストの作成

import React from 'react';

const ThemeContext = React.createContext({
  theme: 'light',
  setTheme: () => {},
});

export default ThemeContext;

親コンポーネント

import React, { useState } from 'react';
import ThemeContext from './ThemeContext';

const Parent = () => {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <div>
        <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
          テーマ切替
        </button>
        <Child />
      </div>
    </ThemeContext.Provider>
  );
};

export default Parent;
import React, { useContext } from 'react';
import ThemeContext from './ThemeContext';

const Child = () => {
  const { theme } = useContext(ThemeContext);

  const style = {
    backgroundColor: theme === 'light' ? '#fff' : '#333',
    color: theme === 'light' ? '#000' : '#fff',
  };

  return (
    <div style={style}>
      <p>テーマ: {theme}</p>
    </div>
  );
};

export default Child;
  • ThemeContext というテーマコンテキストを作成します。このコンテキストには、themesetTheme というプロパティがあります。
  • theme プロパティは、現在のテーマを表す文字列です。
  • setTheme プロパティは、テーマを切り替えるための関数です。
  • 親コンポーネント Parent は、useState フックを使って theme ステートを管理します。
  • 子コンポーネント Child は、useContext フックを使って ThemeContext から theme プロパティを取得します。
  • Child コンポーネントは、theme プロパティに基づいてコンポーネントのスタイルを設定します。

この例では、useState フックを使ってテーマステートを管理し、Context API を使ってそのステートを子コンポーネントに共有しています。

このサンプルコードはあくまでも基本的な例であり、実際のアプリケーションでは状況に応じて様々な拡張を行うことができます。




    Reactにおけるコンポーネント間ステート共有:その他の方法

    Redux Saga:

    • 大規模なアプリケーションにおける非同期処理を含む複雑なステート管理に適したライブラリです。
    • Reduxと組み合わせることで、非同期処理の副作用をカプセル化し、アプリケーションのコードをより予測可能でテストしやすくすることができます。
    • しかし、学習曲線が比較的高く、導入コストも大きくなります。

    MobX:

    • 状態管理を容易にするためにオブザーバブルベースのアプローチを採用したライブラリです。
    • ストア内のステートが変更されると、自動的にビューを更新します。
    • Reduxよりもシンプルで軽量ですが、複雑なアプリケーションには向かない場合があります。

    Zustand:

    • シンプルで使いやすい状態管理ライブラリです。
    • ReduxやMobXよりも軽量で、学習曲線も緩やかです。
    • 小規模から中規模のアプリケーションに適しています。

    Recoil:

    • React Context APIとReduxの機能を組み合わせたようなライブラリです。
    • 宣言型であり、使いやすいインターフェースを提供しています。
    • まだ比較的新しいライブラリですが、注目を集めています。

    カスタムフック:

    • 独自のステート管理ロジックをカプセル化するために、カスタムフックを作成することができます。
    • Context APIやReduxと組み合わせて使用することができます。
    • 柔軟性がありますが、コードが増えて複雑になる可能性があります。

    最適な方法の選択

    コンポーネント間ステート共有に最適な方法は、アプリケーションの規模、複雑性、要件によって異なります。

    • シンプルなアプリケーションであれば、props渡しで十分な場合があります。
    • 複数階層のコンポーネント間でステートを共有する必要がある場合は、Context APIが適しています。
    • 大規模なアプリケーションで複雑なステート管理が必要な場合は、ReduxやMobXなどのライブラリを検討する必要があります。

    それぞれの方法のメリットとデメリットを理解し、状況に応じて適切な方法を選択することが重要です。

      ご参考になりましたでしょうか?


      javascript reactjs react-hooks


      Chrome DevToolsでできる!JavaScriptのデバッグテクニック集

      Chrome DevToolsを使って、JavaScriptコードから直接ブレークポイントを設定することができます。これは、コードの実行を特定の行で一時停止し、変数の値や実行フローを確認するのに役立ちます。手順デベロッパーツールの表示キーボードショートカット: Ctrl + Shift + I (Windows...


      Node.jsでモジュールを理解する:module.exportsとexportsの初心者向けチュートリアル

      Node. jsにおいて、モジュールシステムはコードを分割し、再利用性を高める重要な機能です。モジュールを定義する際に、「module. exports」と「exports」という2つのオブジェクトが使われますが、混同されやすい点も存在します。...


      【初心者向け】ReactでStateとPropsを使いこなすためのポイント

      コンポーネント自身の状態を表します。ユーザー入力や時間経過によって変化します。コンポーネント内でのみアクセス可能で、変更はthis. setState()メソッドを使用して行います。例:ボタンのクリック状態、入力されたテキスト、カウントダウンタイマーの残り時間など。...


      初心者でも安心!JavaScriptでオブジェクトを部分的に複製する方法をわかりやすく解説

      方法 1: Object. assign とスプレッド構文を使うこの方法は、ES2015 以降で利用可能です。このコードでは、まず Object. assign を使って originalObject のコピーを作成します。その後、スプレッド構文を使ってコピーしたオブジェクトに excludedKey プロパティを設定し、値を undefined にすることで、そのキーを除外しています。...


      【初心者向け】React バージョンを確認する3つの簡単な方法

      React のバージョンは、react-dom パッケージのバージョンによって決まります。以下の方法でバージョンを確認できます。方法 1: ブラウザの開発者ツールを使用するブラウザの開発者ツールを開きます。ソース タブに移動します。node_modules フォルダを開きます。...