React QueryとZustandによる楽観的更新パターン
React QueryのonMutate/onError/onSettledコールバックとZustandで、構造化された楽観的UIのワークフローを構築します
「React QueryとZustandによる楽観的更新パターン」はCoddyKit上の無料React Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
React Query の useMutation 概要
React Query の useMutation フックは、3 つのライフサイクルコールバックによって楽観的更新のための基盤を提供します。onMutate はミューテーションの前に実行され、コンテキストオブジェクトを返します。onError は失敗時に実行され、コンテキストを受け取ります。onSettled は成功・失敗にかかわらず実行されます。この構造は、楽観的更新のパターンに特化して設計されています。
onMutate:楽観的更新のフェーズ
onMutate では 3 つの手順を実行します。まず、対象データに対して実行中のクエリをキャンセルします(await queryClient.cancelQueries({ queryKey }))。次に、現在のキャッシュをスナップショットとして保存します(queryClient.getQueryData(queryKey))。最後に、キャッシュに楽観的更新を適用します(queryClient.setQueryData(queryKey, updater))。スナップショットをコンテキストとして返します。
onError:コンテキストを使ったロールバック
onError コールバックは、エラー、ミューテーションの変数、onMutate から返されたコンテキストを受け取ります。コンテキストを使ってロールバックします。queryClient.setQueryData(queryKey, context.previousData) を呼び出してください。コンテキストは、onMutate で取得したスナップショットと onError でのロールバックをつなぐ橋渡しです。
onSettled:同期のための再取得
onSettled コールバックは、成功・失敗にかかわらず実行されます。これを使ってクエリを再取得し、サーバーの状態と同期します。queryClient.invalidateQueries({ queryKey }) を呼び出してください。これにより、ミューテーションが成功した場合(サーバーがデータを変換している可能性があります)でも、失敗した場合(ロールバックが完了しています)でも、最終的にサーバーの正しい状態に一致します。
React Query による楽観的な Todo の切り替え
実践的な例として、todo の completed 状態を切り替えてみましょう。onMutate で todos リストのスナップショットを取得し、キャッシュ内の特定の todo を更新します。onError では、コンテキストからスナップショットを復元します。onSettled では todos クエリを無効化して再取得します。ユーザーには切り替えが即座に反映され、サーバーとの同期はバックグラウンドで行われます。
Zustand の楽観的更新
Zustand ストアでは、楽観的更新を簡単に実装できます。updateItem(id, changes) アクションを作成し、まずストア内のアイテムを即座に更新してから API を呼び出します。API が失敗した場合は、別のアクション revertItem(id, previousState) を呼び出します。Zustand の同期的な状態更新により、楽観的なステップを即座に実行できます。
複雑な更新に Immer と Zustand を使う
Zustand の深くネストされた状態を楽観的に更新する場合は、読みやすいミューテーションのために immer の produce を使います。set(produce(state => { state.items[id] = { ...state.items[id], ...changes } })) のように記述できます。Immer はミュータブルな構文でイミュータブルな更新を処理するため、複雑なネスト状態の変更を読みやすく安全に記述できます。
React 19 の useOptimistic フック
React 19 では、Server Actions 内での楽観的更新のために、組み込みフック useOptimistic(state, updateFn) が導入されました。const [optimisticState, addOptimistic] = useOptimistic(items, (state, newItem) => [...state, newItem]) のように記述します。addOptimistic(newItem) を呼び出すと、サーバーアクションの非同期実行中に UI が即座に更新されます。
useOptimistic による自動ロールバック
useOptimistic はロールバックを自動的に処理します。Server Action が正常に完了した場合でもエラーになった場合でも、React は楽観的な状態を元に戻し、サーバーからの実際の状態を適用します。手動でロールバックロジックを書く必要はありません。アクションの Suspense 境界内で、React が楽観的更新のライフサイクルを管理します。
3 つのアプローチの比較
手動による楽観的更新は完全な制御が可能ですが、定型コードが必要です。React Query の onMutate/onError/onSettled はクエリキャッシュと統合され、自動同期を行います。useOptimistic は Server Actions に対して最も簡単ですが、React 19 とサーバーアクションのアーキテクチャが必要です。データレイヤーに応じて選択してください。単純なローカル状態には手動方式、REST API には React Query、RSC/Server Actions には useOptimistic が適しています。
適切なパターンの選択
楽観的更新のパターンを選ぶときは、アーキテクチャを考慮してください。アプリ全体で React Query を使っているなら、その onMutate パターンは一貫性があり、キャッシュも考慮されています。グローバル状態に Zustand を使っているなら、アクションベースのパターンが自然に適合します。React 19 と Server Actions を使っているなら、useOptimistic が慣用的な選択です。1 つのアプリ内でパターンを混在させることは一般的であり、問題ありません。
React Query の onMutate の戻り値
React Query で onError によるロールバックを可能にするには、onMutate コールバックは何を返す必要がありますか?
レッスンのまとめ:楽観的更新のパターン
React Query の useMutation は、onMutate(クエリをキャンセルし、スナップショットを取得して楽観的更新を適用し、コンテキストを返す)、onError(コンテキストからスナップショットを復元)、onSettled(無効化して再取得)を使います。Zustand の楽観的更新では、状態アクションを即座に呼び出してから API を実行し、失敗時に元に戻します。React 19 の useOptimistic は、Server Actions 内で自動ロールバックを提供します。データレイヤーのアーキテクチャに合ったパターンを選択してください。
よくある質問
「React QueryとZustandによる楽観的更新パターン」レッスンは無料ですか?
はい。「React QueryとZustandによる楽観的更新パターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「React QueryとZustandによる楽観的更新パターン」で何を学びますか?
React QueryのonMutate/onError/onSettledコールバックとZustandで、構造化された楽観的UIのワークフローを構築します ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「React QueryとZustandによる楽観的更新パターン」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 楽観的UIとは何か、いつ使うか
- 楽観的更新の手動実装
- エラー時のロールバックと競合解決
- React QueryとZustandによる楽観的更新パターン