useContext
子は受け取ったcontextは変更できないのか
親から子への一方通行の通信しか出来ないノアk
createContext()
contextを作成する
ProviderとConsumerを返す
useContextを使う場合は、Consumerは使わない
引数はdefault値
たぶん必須
グローバルな場所に定義する
つまり、コンポーネント内に定義するわけではない
そうじゃないと使う側でimportすることができないでしょ
コンポーネント内に定義して、contextそのものをpropsにして渡すとかは?
たぶん出来るけどやるメリットがない
2つの異なるContext同士は会話することはできない
疑問
あとから追加することは出来る?
親で作って子で追加とか
たぶん無理
なので新しいcontextを作る必要がある
もしくはuseReducerと組み合わせてreduxっぽくしてstateを更新するか
Provider
useContext
contextから値を受け取る
使用のモチベーション
プロダクト全体で使うような値
login情報など、プロダクトの全体で使うような値は親に近い場所でcreateしておけば、drillingせずに受け取れるので便利
普通に書いてたら局所的にprop drillingが酷くなった時
つまり、子以下でcreateして孫以下に渡す感じ
propsで渡すものの個数が多いときや、コンポーネントをまたぐ階層が多い時とか
ただし、これをいろんな場所でやるとカオスになりそう
使用例
一番親のappでContext、途中のBでContextBを作ってDに渡している
code:tsx
import * as React from 'react';
import { useContext, createContext } from 'react';
type C = {
app: string;
app2: string;
};
// 何処に定義する?コンポーネント内?
const Context = createContext<C>({
app: '',
app2: ''
});
const App: React.FC = () => {
const app = 'app';
const app2 = 'app2';
return (
<Context.Provider value={{ app, app2 }}>
<A />
</Context.Provider>
);
};
export default App;
// 親 ================================
const A: React.FC = () => {
const a = 'a';
return <B a={a} />;
};
// 子 ================================
const ContextB = createContext({
a: '',
b: ''
});
const B: React.FC<any> = ({ a }) => {
const b = 'b';
return (
<ContextB.Provider value={{ a, b }}>
<C />
</ContextB.Provider>
);
};
// 孫 ================================
const C: React.FC = () => {
const c = 'c';
return <D c={c} />;
};
// 曾孫 ================================
const D: React.FC<any> = ({ c }) => {
const { app } = useContext(Context);
const { a, b } = useContext(ContextB);
return (
<ul>
<li>{app}</li>
<li>{a}</li>
<li>{b}</li>
<li>{c}</li>
<li>d</li>
</ul>
);
};
2022/2/12現在検討中
useContextの無駄な再renderingの防止に
疑問
別ファイルで同名のcontextを作成することはありうるか
以下のような階層のコンポーネントで、AとBで同名のContextを作成し、DでuseContextする
渡しているものは同じ
code:example
A→C→D
B→C→D
無理
Dでimport出来るのはAかBを指定したその一つのみなので。
ってことは、useContextを使う側では、使われる場所は一つに限られるのか
AとDもしくは、BとDは密結合になる
参考
hooks関係ない