0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zustand / React Query を組み合わせた状態管理設計Tips【実務で失敗しないパターン整理】

Posted at

はじめに

フロントエンド案件が複雑化する中で、状態管理は設計の成否を大きく左右します。特に受託開発やSaaS開発では「状態管理が破綻して炎上する」ケースがよく発生します。

この記事では、実務で安定するパターンとして最近採用事例が増えている 「Zustand × React Query構成」 の使い分けと設計方針を整理します。


想定読者

  • 状態管理設計で悩んでいる方
  • Redux疲れしてきた方
  • Next.js+TypeScriptで実務案件を進めたい方

状態管理の責任範囲を切り分ける思想

React Query:APIから取得するサーバー状態(Remote State)
Zustand:ローカル状態(UI状態 / フラグ / 一時保存)

この分離が安定設計のコツです。

  • 永続データ(DB依存) → React Query
  • 一時的なUI状態 → Zustand
  • 認証トークンやセッション管理 → Zustand

React Query の実務ポイント

✅ API呼び出しの型安全設計

import { useQuery } from '@tanstack/react-query';
import { api } from '@/libs/fetcher';

interface User {
  id: number;
  name: string;
}

const { data, isLoading, error } = useQuery(['user', id], () => api<User>(`/api/users/${id}`));
  • queryKey 設計を一貫させる
  • エラーハンドリングは errorBoundary 併用
  • staleTime / cacheTime で無駄リクエスト抑制

✅ 無限スクロール対応も標準機能で安定

import { useInfiniteQuery } from '@tanstack/react-query';

const { data, fetchNextPage } = useInfiniteQuery(
  ['users'],
  fetchUsers,
  {
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  }
);

Zustand の実務ポイント

✅ グローバルUI状態の整理に最適

import create from 'zustand';

type UiState = {
  isSidebarOpen: boolean;
  toggleSidebar: () => void;
};

export const useUiStore = create<UiState>((set) => ({
  isSidebarOpen: false,
  toggleSidebar: () => set((state) => ({ isSidebarOpen: !state.isSidebarOpen })),
}));

✅ Session / Auth情報もZustand管理が楽

type AuthState = {
  token: string | null;
  setToken: (token: string) => void;
};

export const useAuthStore = create<AuthState>((set) => ({
  token: null,
  setToken: (token) => set({ token }),
}));
  • CookieやStorageと併用することも多い
  • Provider不要で手軽に使えるのが強み

よくある失敗パターンと回避策

❌ なんでもZustandに突っ込む

  • API取得結果を全部Zustandに置く
  • キャッシュ無管理 → N+1地獄に

👉 サーバー状態はReact Queryに任せる

❌ ZustandにAPI呼び出し責務を混ぜる

  • 副作用処理をZustand内部に持たせすぎる

👉 API呼び出しは別のサービス層に分離

❌ キャッシュ無効化を意識しない

  • UI再描画のたびに無限リクエスト

👉 staleTime / invalidateQueriesの適切運用


設計分離イメージまとめ

状態 管理先
API取得データ React Query
ローディング・エラー React Query
UI開閉・モーダル表示 Zustand
認証情報 Zustand
フォーム入力中データ Zustand(ケースにより)

状態管理設計のコア思想まとめ

  • サーバー状態はReact Queryに任せる
  • ローカルUI状態はZustandでシンプルに管理
  • 責任範囲を分離すると保守が爆速化する
  • 再利用性・テスト性・拡張性が自然に上がる

おわりに

状態管理は「適材適所の選定」が9割です。
Zustand×React Query構成は今後ますます実務案件の主流になっていきます。

Qiitaでは今後もこういった実務設計に刺さる構成Tipsを発信していきますので、ぜひLGTM・フォローお願いします!


関連タグ

状態管理, Zustand, ReactQuery, TypeScript, Next.js, API連携, SaaS設計, フロントエンド設計, フロントエンド案件, 受託開発

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?