楽観的更新パターン
:LiTarget: 用途
API呼出し前にUIを先に更新して、失敗時にロールバックするパターン。
:LiSparkle: 特徴
- 即時UI反映
- ロールバック
- ローディング不要
:LiCode: コード(コピペ用)
import { useState, useCallback } from 'react';
// 楽観的更新フック(失敗時自動ロールバック)
export function useOptimistic<T>(initial: T) {
const [value, setValue] = useState(initial);
const [pending, setPending] = useState(false);
const [error, setError] = useState<Error | null>(null);
const update = useCallback(async (
next: T,
persist: () => Promise<T>,
) => {
const prev = value;
setValue(next); // 楽観: 即UI反映
setPending(true);
setError(null);
try {
const result = await persist();
setValue(result); // 確定値で上書き
} catch (e) {
setValue(prev); // ロールバック
setError(e as Error);
} finally {
setPending(false);
}
}, [value]);
return { value, update, pending, error };
}
// 使い方:
// const { value, update, error } = useOptimistic(task.done);
// <Checkbox checked={value} onChange={(v) =>
// update(v, () => api.updateTask(task.id, { done: v }))
// } />
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加