導入
このコースで学んだ useState・useContext・useReducer・カスタムフックがあれば、1つの画面の中のことはほぼ何でもできます。ただし実務のアプリはたいてい「複数のページがある」「アプリ全体で共有したい状態が多い」「サーバーのデータを何十か所からも表示する」といった規模になります。ここから先は専用のライブラリに頼るのが定石です。この回は読み物として、それぞれの役割の地図を紹介します。
説明
flowchart TB
subgraph client["クライアント状態(UIの見た目・操作結果)"]
us["useState / useReducer<br/>(1コンポーネント内)"]
ctx["useContext<br/>(狭い範囲で共有)"]
ext["Zustand / Redux Toolkit<br/>(アプリ全体で共有)"]
end
subgraph server["サーバー状態(APIから来るデータ)"]
rq["React Query / SWR<br/>(取得・キャッシュ・再取得を自動化)"]
end
subgraph nav["画面遷移"]
rr["React Router<br/>(1ページ内でURLに応じて切り替え)"]
next["Next.js<br/>(ルーティング+サーバー側描画)"]
end
React Router ―― 画面遷移
React はもともと「1枚のページ」を組み立てる道具なので、複数ページの切り替えは自分では持っていません。React Router が定番で、URL(パス)に応じて表示するコンポーネントを切り替えます。
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function AppRoutes() {
return (
<BrowserRouter>
<nav>
<Link to="/">ホーム</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
- ページを丸ごと再読み込みせずに、ブラウザの「戻る/進む」も自然に動きます。
useParams(URLの一部を取り出す)・useNavigate(コードから遷移する)といったフックも用意されています。
Zustand / Redux Toolkit ―― アプリ全体の状態管理
useContext は便利ですが、値が高頻度で更新される・関係するコンポーネントが非常に多いといった場面では、Context だけで組み立てるのがつらくなってきます。そこで使われるのが専用の状態管理ライブラリです。
- Zustand … 「小さなグローバル
useState」のような感覚で使える軽量ライブラリ。create()でストアを作り、コンポーネントからはただのフックとして呼び出します。 - Redux Toolkit …
useReducerを、アプリ全体・複数ファイルに拡張したような設計です。createSliceで reducer と action をまとめて定義し、useSelector/useDispatchで読み書きします。変更履歴をさかのぼれる開発者ツールなど、大規模開発向けの周辺機能が充実しています。
// Zustand のイメージ(実際に動かすには npm install zustand が必要)
import { create } from "zustand";
const useCartStore = create((set) => ({
items: [],
add: (item) => set((state) => ({ items: [...state.items, item] })),
}));
function CartBadge() {
const items = useCartStore((state) => state.items);
return <span>カート: {items.length}件</span>;
}
この useReducer の考え方(state・action・reducer)が、そのまま Redux Toolkit の設計の元になっています。第5章で reducer を書いた経験は、ここで直接活きます。
React Query(TanStack Query)―― サーバー状態の専門ライブラリ
レッスン18で loading/error/data の3状態を自分で書きましたが、実際のアプリで API 呼び出しが増えるたびに同じボイラープレートを繰り返すのは大変です。React Query はこの「サーバーから来るデータ」専門の管理ライブラリで、次を自動でやってくれます。
- 取得結果のキャッシュ(同じデータを2回取りに行かない)
- ローディング/エラー状態を勝手に管理
- 画面に戻ってきたときの自動再取得、失敗時の自動リトライ
// React Query のイメージ(実際に動かすには npm install @tanstack/react-query が必要)
function UserProfile({ id }) {
const { data, isLoading, isError } = useQuery({
queryKey: ["user", id],
queryFn: () => fetch(`/api/users/${id}`).then((r) => r.json()),
});
if (isLoading) return <p>読み込み中...</p>;
if (isError) return <p>失敗しました</p>;
return <p>{data.name}</p>;
}
- 大事な区別:
useState/useReducer/Zustand/Reduxは「アプリの中だけにある値(クライアント状態)」向け、React Queryは「サーバーが持っている値(サーバー状態)」向けです。両者は性質が違うので、混ぜて1つの道具で管理しようとすると無理が出ます。
まとめ
この章では、実務でよく出てくる「データ取得の型」「再描画を減らす3点セット」「React を取り巻くエコシステムの地図」を学びました。React Router・Zustand/Redux Toolkit・React Query はどれもこのコースでは実際に動かしていませんが、いずれも今回学んだ useState・useContext・useReducer・useEffect の延長線上にあるツールです。手元に Vite でプロジェクトを作り、必要になったタイミングで1つずつ導入してみるのがおすすめです。