Dave Ceddia氏による全5回におよぶReact Hooks入門記事の第5回を本人の許可を得て意訳しました。
誤りやより良い表現などがあればご指摘頂けると助かります。
原文: https://daveceddia.com/usecontext-hook/
すべての新しいReact Hooksの中で議論中のテーマがあります。ほとんど全てが、ファンクションコンポーネントをクラスコンポーネント同等にするために存在しています。
useContext
フックは少し違っています。仕事をよりラクにしてくれるだけのものです。
ReactのContext APIを知らない方のために補足しておきますと、アプリケーション内深くまでデータを渡す方法、それも手動で複数階層にまたがってバケツリレーをせずに済む方法です。データを引き回すことさえできれば良いという時には、Reduxのようなツールの代替手段として機能します。Contextについて学び、Reduxとの違いを知るにはこちらへどうぞ。
この記事では、 useContext
がどのようにContextを扱いやすくするのかを見ていきます。
メモ:Hooksは現在α版であり、プロダクション環境ではまだ使用できません。APIはさらに変更される可能性があるため、現時点ではプロダクションアプリの書き換えはオススメしません。Open RFCにコメントし、公式ドキュメントやFAQにも目を通してください。
従来の一般的な方法
典型的なContext APIの使用例はこのような感じです。
import React from "react";
import ReactDOM from "react-dom";
// Contextを生成する
const NumberContext = React.createContext();
// 2つの値を持つオブジェクトを返す
// { Provider, Consumer }
function App() {
// Providerを活用して値を全ての
// 子要素と孫要素に利用可能にする
return (
<NumberContext.Provider value={42}>
<div>
<Display />
</div>
</NumberContext.Provider>
);
}
function Display() {
// Consumerを活用してcontextから取得した値を使う
// このコンポーネントはpropsを取らないことに注意!
return (
<NumberContext.Consumer>
{value => <div>The answer is {value}.</div>}
</NumberContext.Consumer>
);
}
ReactDOM.render(<App />, document.querySelector("#root"));
Context APIについて詳しくはこちらで触れています。
useContextを使ったモダンな方法
Display
を useContext
フックを使ってリファクタして、どのような感じになるか見てみましょう。
// useContextをimportする(もしくはReact.useContextを使う)
import React, { useContext } from 'react';
// ...
function Display() {
const value = useContext(NumberContext);
return <div>The answer is {value}.</div>;
}
これだけです。 useContext
を呼び、 React.createContext
から取得できるcontextオブジェクトを渡すと、値が利用可能になります。見やすくなったでしょう?
注目すべき唯一のポイントは、contextオブジェクトを丸ごと useContext
に渡さなければならないということです。consumerだけではダメです!もし忘れるとReactが警告してくれますが、忘れないでくださいね?
ネストされたConsumer
コンポーネントが複数の親contextからデータを受け取りたいような場合はこうなります。
function HeaderBar() {
return (
<CurrentUser.Consumer>
{user =>
<Notifications.Consumer>
{notifications =>
<header>
Welcome back, {user.name}!
You have {notifications.length} notifications.
</header>
}
}
</CurrentUser.Consumer>
);
}
たった2つの値を受け取るのにひどいネストになってしまいます。 useContext
を使って良い感じにしてみましょう。
function HeaderBar() {
const user = useContext(CurrentUser);
const notifications = useContext(Notifications);
return (
<header>
Welcome back, {user.name}!
You have {notifications.length} notifications.
</header>
);
}
ずっと読みやすくなりましたね。
広がるHooksの世界
今週カバーした以外にも多くのHooksがあります。メモ作成のための useMemo
のような素晴らしいものありますので、ぜひ公式のHooks APIドキュメントで学んでみてください。公式ドキュメントも素晴らしいですが、Hooks入門から始めることをおすすめします。
Hooksウィークに投稿した私の他の記事も再掲します。
毎週記事を投稿しています(ビデオもたまに)。もっと情報が必要であれば、ボックスにメールアドレスを登録してください。