はじめに
Web アプリのUI開発において、楽観的更新(Optimistic Update)はUXを向上させる強力な手法としてよく推奨されます。サーバーの応答を待たずに画面を先に書き換えるため体感が速く、「とりあえず楽観的更新にしておけば間違いない」という空気すらあります。
ただ、その定石をすべての操作にそのまま当てはめてよいのか迷う場面があります。整理してみると、UIの更新戦略は開発者の好みや一般論ではなく、「失敗時の影響度(リスク)」という明確な基準から判断できます。
本稿ではその使い分けの考え方と、React 19(useOptimistic)および Next.js の Server Actions を題材にした実装上の落とし穴について共有します。
判断基準:「仮の表示」が外れたときのリスク
使い分けの基準となるのは、パフォーマンスや好みではなく、シンプルに「エラー時の影響度」です。
サーバーの確定を待たずに見せた"仮の表示"が間違っていた場合、ユーザーにどのような影響があるか。
楽観的更新は「処理が成功する」という前提で先に画面を書き換える手法です。そのため、万が一その前提が崩れた際のリスクを想像すると、自然と使い分けが見えてきます。ここで確認しておきたいのは、以下の2つの観点です。
- 失敗時の影響 — 仮の成功表示を信じて、ユーザーが取り返しのつかない操作へ進んでしまわないか
- やり直しのしやすさ — 失敗したことにすぐ気づけて、簡単に再操作できるか
たとえば「いいね」や「お気に入り」のトグル操作を考えてみます。仮に処理が失敗しても、「ハートが一瞬点いて元に戻る」だけなので大きな問題にはなりにくく、もう一度ボタンを押せば済みます。このように失敗時の影響が小さく、回復も容易な操作は、楽観的更新に適しています。
逆に、「投稿を非公開に切り替える」ような操作は話が別です。「非公開にしました」と先に見せて実は失敗していたら、プライバシーの事故に繋がります。ブロックや、取り消せない削除も同じです。こういった操作は、応答を待ってから画面を変える悲観的更新(または事前確認のダイアログ)にするのが正解です。
実装の違い:React 19useOptimisticを用いた定石
基準が決まれば、あとは実装です。違いは「UI 更新をサーバー応答の前に行うか後に行うか」の一点に尽きます。現在であれば、React 19 の useOptimistic を使うのが自然です。
楽観的更新:先に UI を更新し、失敗したら自動で戻
const [optimisticFav, setOptimisticFav] = useOptimistic(isFavorited);
function handleToggleFavorite() {
startTransition(async () => {
setOptimisticFav(!isFavorited); // ① 楽観的に即反映(保留中だけ有効)
try {
await toggleFavorite(id); // ② サーバーへリクエスト
} catch {
// 巻き戻しは useOptimistic が自動でやるため、ここでは失敗を伝えるだけ
toast.error("保存に失敗しました", {
action: { label: "再試行", onClick: handleToggleFavorite },
});
}
});
}
楽観的更新の弱点は「失敗しても無言で元に戻る」ことですが、上記のようにトーストで失敗を知らせ、再試行ボタンを添えるだけでユーザビリティは大きく底上げされます。
悲観的更新:結果を待ってから UI を更新す
async function handleTogglePrivate() {
setLoading(true);
try {
const ok = await togglePrivate(id);
if (!ok) return; // 失敗:UI は変えない
setIsPrivate(!current); // ③ 成功を確認してから画面を更新
} finally {
setLoading(false);
}
}
実装の落とし穴①:連打による競合(レースコンディション)
楽観的更新を採用する際、実務で必ず考慮すべきなのが「ユーザーがボタンを高速で連打したケース」です。
楽観的更新はUIが即座に切り替わるため、ユーザーはストレスなく連続してクリックできてしまいます。このとき、サーバーへ送るリクエストが単なる「現在の状態を反転させる」処理だと危険です。ネットワークの遅延によってリクエストの到達順序が前後(追い越し)した場合、サーバー側の最終的な状態と、画面の表示にズレが生じてしまいます。
…
記事の続きは下のURLをクリック!
https://rightcode.co.jp/blogs/56372
もっと上を目指したあなたへ
現在、ライトコードでは「WEBエンジニア」「データエンジニア」「ゲーム・XRエンジニア」「UI/UXデザイナー」「PM/PMO」などのポジションで積極採用中です!
ライトコードは、技術力に定評のある受託開発をメインにしているIT企業。
有名WEBサービスやアプリの受託開発などの企画、開発案件が目白押しの状況です!
- もっと大きなことに挑戦したい!
- エンジニアとしてもっと成長したい!
- モダンな技術に触れたい!
現状に満足していない方は、まずは一度、【Wantedly内の弊社ページ】をのぞいてみてください。