Reactアプリが少しずつ大きくなってくると、「この値、どの画面でも使いたい」「ログインユーザーを全画面で保持したい」みたいなニーズが出てくる。
そのとき使うのがグローバル状態管理。
Reactにはいくつか方法があるけど、今回は実務でよく出てくるContext APIと、使いやすくて軽量なZustandを紹介する。
Reactに標準で備わってる「どこからでも状態を読み書きできる仕組み」。
小〜中規模アプリならこれで十分。
tsx
// 1. Contextを作成
const UserContext = createContext<UserContextType | undefined>(undefined);
// 2. Providerで囲む
<UserContext.Provider value={{ username, login, logout }}>
{children}
</UserContext.Provider>
// 3. useContextで中身を読む
const { username } = useContext(UserContext);
tsx
export const useUser = () => {
const context = useContext(UserContext);
if (!context) throw new Error("UserProviderが必要です");
return context;
};
→ 毎回useContext(UserContext)
って書かなくてよくなる
メリット | デメリット |
---|---|
標準機能で導入コストなし | 値が変わると全てのコンポーネントが再レンダリングされる |
TypeScriptで型安全に設計できる | グローバルにしたくないものまで広がりやすい |
カスタムフック化で簡潔に | ネストが深くなるとProvider地獄になることも |
「もっと手軽に」「シンプルに」「効率よく」状態を共有したいときに使える軽量ライブラリ。
Reduxほど重くなく、Contextより効率がいい。
bash
npm install zustand
tsx
// store.ts
import { create } from 'zustand';
type Store = {
username: string;
login: (name: string) => void;
logout: () => void;
};
export const useUserStore = create<Store>((set) => ({
username: '',
login: (name) => set({ username: name }),
logout: () => set({ username: '' }),
}));
tsx
const { username, login } = useUserStore();
Provider不要
(どこでも使える)分割再レンダリング対応
(必要な部分だけ再描画)シンプルなAPI
で導入が楽シーン | おすすめ |
---|---|
小〜中規模、標準で済ませたい | Context API |
状態が多い、大規模、効率重視 | Zustand |
Providerが多すぎてつらい | Zustand |
状態のセレクター管理がしたい | Zustand |
👇 サンプル:Context APIで認証状態を管理するアプリ
👇 サンプル:Zustandで認証状態を管理するアプリ