楽観的更新の手動実装
ローカルで楽観的に状態を更新し、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フィードバックを取得できます。ローカル設定は不要です。