React初心者がグローバルなstate管理について勉強した時のメモです。
現状
以下のような階層構造の時に、
App → ComponentA → ComponentB → ComponentC
ComponentCにあさひ
というUser名の値を渡したい場合、各Componentでpropsのバケツリレーをしないといけない。
import { ComponentA } from "./components/ComponentA";
export const App = () => {
const name = "あさひ";
return (
<>
<ComponentA name={name} />
</>
);
};
import { ComponentB } from "./ComponentB";
export const ComponentA = (props) => {
const { name } = props;
return (
<>
<p>ComponentA</p>
<ComponentB name={name} />
</>
);
};
import { ComponentC } from "./ComponentC";
export const ComponentB = (props) => {
const { name } = props;
return (
<>
<p>ComponentB</p>
<ComponentC name={name} />
</>
);
};
export const ComponentC = (props) => {
const { name } = props;
return (
<>
<p>ComponentC</p>
<p>{name}</p>
</>
);
};
Contextを使ったstate管理
Providerの作成
Providerを作成します。
import React, { createContext } from "react";
export const UserContext = createContext({})
export const UserProvider = (props) => {
const { children } = props;
const contextName = "あさひ"
return (
<UserContext.Provider value={{ contextName }}>
{children}
</UserContext.Provider>
)
}
ここで今回受け渡したい値のUser名あさひ
を設定します。
createContext
を使用し以下のように囲うことで{children}
に入ってくるコンポーネントではどこでもvalueの値を参照することができます。
<UserContext.Provider value={{ contextName }}>
{children}
</UserContext.Provider>
import { ComponentA } from "./components/ComponentA";
import { UserProvider } from "./provider/UserProvider";
export const App = () => {
return (
<UserProvider>
<ComponentA/>
</UserProvider>
);
};
作ったProviderコンポーネントをApp.jsxでComponentAを囲います。
これでComponentA以下の全てのComponentでProviderで設定した値の参照ができます。
useContext
useContext
を使用してComponentCで値を取得します。
今回はUserContext
のcontextName
を取得しています。
import { useContext } from "react";
import { UserContext } from "../provider/UserProvider";
export const ComponentC = () => {
const name = useContext(UserContext);
return (
<>
<p>ComponentC</p>
<p>{name.contextName}</p>
</>
);
};
useStateと使う場合
useStateと一緒に使うことでstateを渡すことができます。
ProviderでuseStateを定義し、valueに値を設定します。
今回はカウントアップのためのstateをComponentCに渡していきます。
import React, { createContext, useState } from "react";
export const UserContext = createContext({});
export const UserProvider = (props) => {
const { children } = props;
const [count, setCount] = useState(0);
return (
<UserContext.Provider value={{ count, setCount }}>
{children}
</UserContext.Provider>
);
};
import { useContext } from "react";
import { UserContext } from "../provider/UserProvider";
export const ComponentC = () => {
const { count, setCount } = useContext(UserContext);
return (
<>
<p>ComponentC</p>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>ボタン</button>
</>
);
};
useContextでProviderでセットしたstateを受け取ることで使用できます。
めっちゃ便利!!