おーみんブログ

C#, ASP.NET Core, Unityが大好きです。

【React】useContextを用いてグローバルにデータ共有を行う

はじめに

React hooksの1つであるuseContextを用いる機会があったので備忘録として記載します。

useContextについて

Reactでは通常データ共有の際にpropsを用いてコンポーネント間でデータのやり取りを行いますが、useContextを用いることでその制限がなくなります。
propsでの受け渡しも小規模アプリなら問題ないのですが、規模が大きくなってコンポーネントが増えてくると結構大変なのです...。

サンプルコード

以下はuseContextで定義したデータを別のコンポーネントで利用するサンプルコードです。

props等で受け渡しを行っていませんがデータへアクセスできることがuseContextのメリットとなります。

●useContext側

type HogeContextType = {
    hoges: Hoge[];
    setHoges: Dispatch<SetStateAction<Hoge[]>>;
};

// Context生成
const HogeContext = createContext<HogeContextType>({} as HogeContextType);

export const HogeProvider = (props: { children: ReactNode }) => {
    const { children } = props;
    
    // 共有するデータをuseStateで管理
    const [hoges, setHoges] = useState<Hoge[]>([]);

    // Providerのvalue値に共有するデータを記載
    return (
        <HogeContext.Provider value={{ hoges, setHoges }}>
            {children}
        </HogeContext.Provider>
    );
};

export const useHoges = (): HogeContextType => useContext(HogeContext);

●useContextを利用したいコンポーネントをProviderで囲む

function App() {
    return (
        <div className="App">
            <HogeProvider>
                <Index />
            </HogeProvider>
        </div>
    );
}

export default App;

●useContextを扱う側(カスタムフック)

export const useHogeHoge =() => {
    const { hoges, setHoges } = useHoges();

    const getHoges = useCallback(() => {
        axios
            .get<Hoge[]>(`${commonData.baseUrl}/api/hoges`)
            .then((response) => setHoges(response.data))
            .catch((response) => {console.log(response)})
    },[hoges]);
    return { getHoges , hoges, setHoges }
}

●useContextを扱う側(View)

export const Index: FC = memo(() => {
    // カスタムフックでuseContext側で定義したデータを呼び出し
    const { getHoges , hoges, setHoges } = useHogeHoge();

    const handleClick = () => {
        // useContextで作ったデータを変更
        setHoges([...hoges, 'newHoge']);
    }

    return (
        <button onClick={() => handleClick} />
    )
})

おわりに

Reduxも勉強していたのですが、明らかにuseContextを利用したほうがやりやすいですね(;´∀`)
今後もどんどん使っていこうと思います!