0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React hooksを理解する(useContext)

Posted at

目次

  • Context とは?
  • useContext の基本的な使い方
  • useContext を使うメリット
  • 実践例
  • useContext の注意点
  • まとめ

Contextとは?

ReactのContextは、ツリー状のコンポーネント全体でデータを共有する仕組みです。

通常、Reactではpropsを使ってデータを親コンポーネントから子コンポーネントに渡しますが、Contextを使うとどの階層にあるコンポーネントでも直接データを取得 できます。

image.png

image.png

Context の主な特徴

  • データの「グローバルな状態管理」が簡単になる
  • 子コンポーネントでpropsを繰り返し渡す必要がなくなる
  • 状態やテーマ設定、認証情報などをコンポーネント全体で共有しやすい

useContextの基本的な使い方

1. Contextを作成

以下に、テーマを切り替えるためのThemaContextを作成し、使用する例を示します。


import React, { createContext, useState, useContext } from "react";

// Context を作成
const ThemeContext = createContext();

2. Context を提供 (Provider)

ThemeProvider Componentは、ThemeContext.Provider を使ってContextの値を設定し、提供します。
このContextは、テーマに関するデータ(theme)と、テーマを切り替える関数(toggleTheme)を持ちます。


function ThemeProvider({ children }) {
  const [theme, setTheme] = useState("light");

  // テーマを切り替える関数
  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
  };

  // Context に渡す値を指定
  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

childrenをラップすることで、どのComponentでもContextの値にアクセスできるようになります。

3. Contextを消費 (UseContext)

useContextフックを使うことで、Contextの値を直接取得します。


function ThemeSwitcher() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <div style={{ background: theme === "light" ? "#fff" : "#333", color: theme === "light" ? "#000" : "#fff" }}>
      <p>現在のテーマ: {theme}</p>
      <button onClick={toggleTheme}>テーマを切り替え</button>
    </div>
  );
}

4. アプリ全体で使用する


function App() {
  return (
    <ThemeProvider>
      <ThemeSwitcher />
    </ThemeProvider>
  );
}

export default App;

useContextを使うメリット

1. props を繰り返し渡す必要がない

子や孫コンポーネントにデータを渡すとき、親から順番にpropsを伝播させる必要がなくなる

2. コードがシンプルに

useContext を使うと、直接必要な値を取得できるため、コードが簡潔になる

3. グローバルな状態管理

コンポーネント間で共通のデータ(例: ユーザー情報、テーマ設定など)を管理しやすい

実践例

ここでは、カートのアイテム数を Context で管理する例を紹介します。

Contextの作成


import React, { createContext, useState, useContext } from "react";

// カートの Context を作成
const CartContext = createContext();

Providerの作成


function CartProvider({ children }) {
  const [cartItems, setCartItems] = useState([]);

  // アイテムを追加する関数
  const addToCart = (item) => {
    setCartItems([...cartItems, item]);
  };

  return (
    <CartContext.Provider value={{ cartItems, addToCart }}>
      {children}
    </CartContext.Provider>
  );
}

カートを表示するコンポーネントでContextを使う


function Cart() {
  const { cartItems } = useContext(CartContext);

  return (
    <div>
      <h2>カートの中身:</h2>
      <ul>
        {cartItems.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

アイテムをカートに追加するコンポーネントでContextを使う


function AddItemButton({ item }) {
  const { addToCart } = useContext(CartContext);

  return <button onClick={() => addToCart(item)}>{item}」をカートに追加</button>;
}

全体をラップする


function App() {
  return (
    <CartProvider>
      <AddItemButton item="りんご" />
      <AddItemButton item="オレンジ" />
      <Cart />
    </CartProvider>
  );
}

export default App;

useContextの注意点

1. 大規模アプリでは複雑化しやすい

  • 複数のContextを作成する場合、それぞれのProviderでラップする必要があり、コードが見づらくなることがあります。
  • ReduxやZustandなどの状態管理ライブラリを使うことも検討しましょう。

2. 不要な再レンダリングに注意

  • Contextに依存するすべてのコンポーネントが、値の変更時に再レンダリングされます。
  • 性能が気になる場合は、値を分割するか、React.memo を活用するのが良いです。

3. 依存関係の管理が重要

  • Contextの値を変更する処理が複雑になると、管理が難しくなることがあります。

まとめ

  • useContext は React の Context を簡単に使うためのフックで、グローバルなデータ共有に役立つ
  • 手順
    1. createContext で Context を作成
    2. Provider を使って値を渡す
    3. 子コンポーネントで useContext を呼び出して値を取得・操作する
  • テーマ管理、認証情報、カート機能など、複数のコンポーネントで同じデータを使う場合に便利
  • ただし、大規模アプリではReduxなどの状態管理ライブラリを使うことも検討すると良い
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?