0Pricing
React Academy · レッスン

楽観的更新の手動実装

ローカルで楽観的に状態を更新し、Mutationをキューに入れ、成功・失敗のケースを明示的に処理します

「楽観的更新の手動実装」はCoddyKit上の無料React Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

ミューテーション前の状態

手動で楽観的更新を行う場合は、サーバーのデータをもとに初期化したコンポーネントのローカル状態から始めます。const [items, setItems] = useState(serverItems)のように記述します。このローカル状態をレンダリングし、楽観的に変更します。サーバーから取得したデータを直接変更してはいけません。自分で管理できるローカルコピーを保持してください。

楽観的更新の手順

ユーザーがミューテーション(「追加」「いいね」「削除」のクリックなど)を実行したら、APIを呼び出す前に状態をすぐ更新します。setItems(prev => [...prev, newItem])のように記述します。UIには変更が即座に反映されます。この更新を行った後で、実際のネットワークリクエストを実行します。

以前の状態の取得

楽観的更新を行う前に、現在の状態を取得します。const previousItems = itemsのように記述します。このスナップショットがロールバック先になります。API呼び出しが失敗した場合は、この値を復元します。保留中のミューテーションの間だけ必要なので、状態ではなく変数に保存してください。

API呼び出しの実行

楽観的更新の後、APIを非同期で呼び出します。try/catchで囲んでください。成功した場合は、サーバーの状態と同期するために再フェッチすることもできますし、サーバーが同じデータを返すのであれば、楽観的な状態をそのまま信頼することもできます。失敗した場合は、取得しておいた以前の状態を使ってロールバックします。

失敗時のロールバック

ミューテーションのcatchブロックで、setItems(previousItems)を実行します。これにより、楽観的更新前の状態に戻ります。ロールバックの後にエラー通知を表示してください。まれな失敗が起きることはユーザーも理解できますが、受け入れられないのは、気づかれないまま不整合が残ることです。

失敗時にエラートーストを表示する

ロールバックした後、「変更を保存できませんでした。もう一度お試しください。」というエラーメッセージを表示し、同じミューテーションを再実行する「再試行」ボタンを設けます。これにより、ユーザーが自分で対処できるようになります。ロールバック、エラートースト、再試行を組み合わせることで、UI全体をブロックせずに失敗を適切に処理できます。

一時IDの問題

新しい項目を楽観的に追加するとき、サーバーはまだ実際のIDを割り当てていません。楽観的な項目には一時IDを作成します。const tempId = crypto.randomUUID()のように記述します。このIDをリスト内の項目のキーとして使用します。APIが成功を返したら、一時IDをサーバーが割り当てた実際のIDに置き換えます。

一時IDの調整

作成ミューテーションが成功すると、サーバーは実際のIDを返します。状態を更新して、一時的な項目を置き換えます。setItems(prev => prev.map(item => item.id === tempId ? { ...item, id: serverResponse.id } : item))のように記述します。この調整により、以降の操作で正しいサーバーIDを使用できます。

競合状態の問題

ユーザーが短時間に2つのミューテーションを実行すると、レスポンスが順不同で到着することがあります。2つ目のミューテーションのレスポンスが1つ目より先に到着し、1つ目のロールバックによって、2つ目による正しい状態が上書きされる可能性があります。これは楽観的UIに特有の競合状態です。

競合を防ぐためのミューテーションの直列化

競合状態への対策の一つは、キューを使ってミューテーションを直列化することです。ミューテーションの実行中は、トリガーボタンを無効にします(isSubmitting 状態を true に設定します)。前のミューテーションが完了してから、次のミューテーションだけを許可します。応答性は多少犠牲になりますが、状態の順序が正しく保たれることを保証できます。

削除の楽観的更新パターン

削除操作では、まず以前のアイテムを保存し、状態から削除対象のアイテムを除外してから、削除 API を呼び出します。失敗した場合はロールバックします。削除は作成よりも単純です(ID の照合が不要なため)が、基本的な原則は同じです。API を呼び出す前に短い待機時間を設け、「元に戻す」オプションを表示することも検討してください。

楽観的更新での一時 ID

楽観的に追加するアイテムに一時 ID が必要なのはなぜですか?

レッスンのまとめ:手動による楽観的更新

手動パターンでは、previousItems を保存し、新しい状態で setItems を呼び出してから API を呼び出します。失敗した場合は setItems(previousItems) でロールバックし、エラーを表示します。追加では crypto.randomUUID() を一時 ID として使い、成功時にサーバーの ID と照合します。実行中のミューテーションのトリガーを無効にして、競合状態を防ぎます。ロールバック + トースト + 再試行が、標準的な失敗時の UX です。

よくある質問

「楽観的更新の手動実装」レッスンは無料ですか?

はい。「楽観的更新の手動実装」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「楽観的更新の手動実装」で何を学びますか?

ローカルで楽観的に状態を更新し、Mutationをキューに入れ、成功・失敗のケースを明示的に処理します ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「楽観的更新の手動実装」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 楽観的UIとは何か、いつ使うか
  2. 楽観的更新の手動実装
  3. エラー時のロールバックと競合解決
  4. React QueryとZustandによる楽観的更新パターン
← React Academyに戻る