なんとく知っていた Context API を理解する
なんとなく知っていたこと
- props として渡さなくても上位コンポーネントのデータにアクセスできる
- prop drilling を避けれる
- react-redux のProvider の Pure React版
説明
Context API は 簡単にまとめると createContext 関数を介して生成した Context をその Context 自身が持つ
Provider という React Component で データを共有したいコンポーネント群をラップすることで
どこの階層のコンポーネントからもデータにアクセスできるような仕組みのことです
これにより、下記のように 子コンポーネントでは使用しないが孫コンポーネントで使用するためだけに
props を受け渡すようなケース(props drilling)を回避できます
(今回の例はすごくシンプルなので問題になりませんが、規模や階層が増えてくるとカオスになります)
親->(props1)->子->(props1)->孫
それでは上記の例を実際にコードに起こしてみようと思います
Context API を使用しない場合
import React from 'react'; const Parent = () => { return ( <Child text="for grandchild" /> ); }; // Child は受け取ってGrandChildに渡すだけ const Child = ({ text }) => { return ( <GrandChild text={text} /> ); }; const GrandChild = ({ text }) => { return ( <p>{text}</p> ); }; export default Parent;
Context API を使用する場合
import React from 'react'; const TextContext = React.createContext() const Parent = () => { return ( <TextContext.Provider value="for grandchild"> <Child /> </TextContext.Provider> ); }; const Child = ({ text }) => { return ( <GrandChild /> ); }; const GrandChild = ({ text }) => { return ( <TextContext.Consumer> {(text) => <p>{text}</p>} </TextContext.Consumer> ); }; export default Parent;
このように createContext 経由で生成した context の Provider と Consumer を駆使することにより
props を経由せずにデータの受け渡しができます
Context の使い所
- 一連のコンポーネント群の大部分で使用するようなデータがあるとき(テーマ情報など)
- Atomic Design を採用している場合(props drilling の回避)
pros/cons
pros
- props drilling を回避できる
cons
- 多用しすぎるとデータフローが分かりづらくなる可能性あり
思うこと
すでにprops drilling 状態になっているものに対しても導入が楽そう
Redux の代用になるのでは?!みたいな記事がわりと出てるけど、そもそもコンセプトが違うので個人的にはそれはなしだと思ってる
(工夫次第でそれっぽいものはできそう)