🚀 新規事業

undo-pattern

最終更新 2026年05月09日 / 40_新規事業/SCALE_Build/カタログ/機能集/undo-pattern.md

Undo(取り消し)パターン

用途

削除・編集を取り消せるUndoパターン。トースト+タイマー方式。

特徴

  • トースト連携
  • タイマー
  • バックエンド連携

コード(コピペ用)

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 } });
// };

使い方

対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。

注意事項

  • 依存パッケージを忘れず追加