Undo(取り消し)パターン
:LiTarget: 用途
削除・編集を取り消せるUndoパターン。トースト+タイマー方式。
:LiSparkle: 特徴
- トースト連携
- タイマー
- バックエンド連携
:LiCode: コード(コピペ用)
import { useRef } from 'react';
// Undo フック(5秒以内なら取り消し可能・期限後にcommit)
export function useUndoableAction<T>(commitMs = 5000) {
const pending = useRef<{ undo: () => void; commit: () => Promise<void>; timer: ReturnType<typeof setTimeout> } | null>(null);
const start = (
optimistic: () => void,
commit: () => Promise<void>,
undo: () => void,
): { cancel: () => void } => {
optimistic();
if (pending.current) { clearTimeout(pending.current.timer); pending.current.commit(); }
const timer = setTimeout(async () => { await commit(); pending.current = null; }, commitMs);
pending.current = { undo, commit, timer };
return {
cancel: () => {
if (!pending.current) return;
clearTimeout(pending.current.timer);
pending.current.undo();
pending.current = null;
},
};
};
return { start };
}
// 使い方:
// const { start } = useUndoableAction();
// const handleDelete = (item) => {
// const action = start(
// () => removeFromUI(item),
// () => api.delete(item.id),
// () => addBackToUI(item),
// );
// toast({ msg: '削除しました', action: { label: '取消', onClick: action.cancel } });
// };
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加