React コンテキストの使い方(useContext)
コンテキストについて
下記の公式ドキュメントでコンテキストはこのように説明されています。
「コンテクストは各階層で手動でプロパティを下に渡すことなく、コンポーネントツリー内でデータを渡す方法を提供します。」
コンテキストを導入していない場合は、ステートが定義した親コンポーネントから子、孫コンポーネントへプロップで渡していく必要があります。
コンテキストを導入すると、上記のようにコンポーネント間でステートを受け渡しすることなく、ステート、イベントハンドラを一元管理して、必要な場所で呼び出すようにできるようになります。
なぜコンテキストを使うのか
コンテキストを使うメリットは下記の3点あります。コンテキストを使うことでUIとロジックが分離することができるのでより開発しやすいコードになります。
- 複数コンポーネントで同じステートを簡単に操作できる
- ステート、イベントハンドラを一元管理できる
- 親コンポーネントから子、孫コンポーネントへプロップスを使って渡す必要がなくなる
コンテキストの使い方
コンテキストの使い方について説明します。コンテキストは下記の手順で使うことができます。まず、コンテキストを作成し、その作成したコンテキストのプロバイダーに値を渡します。そして、useContextフックを使ってプロバイダーに渡した値を取得します。上記の流れをコードを見ながら説明します。
1.コンテキストを作成する
2.コンテキストプロバイダーに値を渡す
3.useContextフックを使ってデータを取得する
今回は下記の公式ドキュメントの例を参考にコンテキストの使い方を説明します。
表示されるのはボタンをクリックすると、値が増えるカウンターです。
ステートの使い方がわからない方はリンクの内容を参考にしてください。
1.コンテキストを作成する
import React, { createContext } from 'react';
export const CountContext = CreateContext();
CreateContext
を使ってCountContext
というコンテキストを作成します。
2.コンテキストプロバイダーに値を渡す
import React, { createContext, useState } from 'react';
export const CountContext = CreateContext();
const [count, setCount] = useState(0);
const addCount = () => {
setCount(count + 1);
};
<CountContext.Provider value={{count, addCount}}>
<App />
</CountContext.Provider>
上記のコードの下記の箇所でコンテキストプロバイダーに値を渡しています。
コンポーネントをプロバイダーで挟むことで渡した値を呼び出すことができるようになります。
下記のコードによって、CountContext.Provider
が挟んでいるApp
コンポーネントでvalue
に渡した{count, addCount}
を呼び出し可能になりました。
<CountContext.Provider value={{count, addCount}}>
<App />
</CountContext.Provider>
下記のコードはコンテキストに直接関係はありませんが念のため内容を説明します。
useStateを使ってステートの値count
と、それを更新するための関数setCount
を定義します。
そして、ボタンを押した時のイベントハンドラのaddCount
を定義します。
内容はステートcount
の値に+1する処理です。
const [count, setCount] = useState(0);
const addCount = () => {
setCount(count + 1);
};
3.useContextフックを使ってデータを取得する
上記まででプロバイダーに渡した値を渡してApp
コンポーネントで呼び出すことが可能になりました。次にその値の呼び出し方について説明します。
export const App = () => {
// プロバイダーに渡した値を呼び出す
const {count, addCount} = useContext(CountContext)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={addCount}>
Click me
</button>
</div>
);
}
上記の下記の箇所がプロバイダーに渡した値を呼び出している箇所になります。
useContext
を使ってCountContext
からプロバイダーに渡した値のcount
,addCount
それぞれを呼び出しています。
// プロバイダーに渡した値を呼び出す
const {count, addCount} = useContext(CountContext)
以上で説明は終わりです。
また、CountProvider.js
を下記のようにuseMemo
を使うことで最適化できます。
ステートの内容が変わるたびに再レンダリングされるのでステートの数が多くなるとレンダリングのコストが大きくなっていきます。useMemoを使うと最新の値と前の値を比較して必要な箇所だけ計算が行われます。それによってレンダリング毎に複雑な計算をされることを避けることができます。
詳しく知りたい方は下記の公式ドキュメントを参考にしてください。
export const useCount = () => {
const [count, setCount] = useState(0);
const addCount = () => {
setCount(count + 1);
};
const providerValue = useMemo(() => ({count, addCount}), [count]);
return providerValue;
}
const providerValue = useCount();
<CountContext.Provider value={providerValue}>
<App />
</CountContext.Provider>
以上です。読んでいただきありがとうございました。
誤字、脱字、間違い等ありましたらコメント頂ければ幸いです。
Discussion