🪐

Reactでボタン連打を防ぐ簡単なcallback関数

2022/03/11に公開

背景

ボタン連打された時に同じ処理が複数回走ってしまうと困るので、連打されても大丈夫なようにしたい。
useStateは再描画までの間にボタンを押せてしまう可能性があるかも...と考えた。

この実装をした時の挙動

  • ボタンの連打は可能だが、押しても処理が実行されないようになる
  • 処理が終わったら次の処理を実行可能になる

この実装ではできないこと

  • ボタンを押した瞬間にボタンを非活性にする
  • ボタンを押した後、一定時間は処理を行わない
  • 並列で同時に呼ぶと両方実行されてしまう
    (が、jsはシングルスレッドだから問題にならないよね?)

解決方法

useLockCallback.ts
import { DependencyList, MutableRefObject, useCallback } from 'react';

const useLockCallback = (
  callback: () => Promise<void>,
  ref: MutableRefObject<boolean>,
  deps: DependencyList
) => {
  return useCallback(() => {
    // 処理中であれば処理終了、処理中でなければ処理開始
    if (ref.current) return;
    ref.current = true;
    // 処理が終わったらフラグを下げる
    callback().finally(() => (ref.current = false));
  }, deps);
};

export default useLockCallback;

Discussion