🪐
Reactでボタン連打を防ぐ簡単なcallback関数
背景
ボタン連打された時に同じ処理が複数回走ってしまうと困るので、連打されても大丈夫なようにしたい。
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