react-use icon indicating copy to clipboard operation
react-use copied to clipboard

Hook Proposal: useTimeoutControlledFn — a manual version of useTimeoutFn

Open muradsofi opened this issue 6 months ago • 1 comments

useTimeoutFn, starts the timeout automatically on mount. In our case, we needed something similar but fully manual which is a timeout only starts when we explicitly trigger it (e.g., after an API success).

Why this might be useful

  • No automatic timeout on mount
  • Full control: start(), cancel(), reset()
  • Ability to reuse the last delay (reset)
  • Useful in callbacks, controlled UI flows, etc.

API

const [isReady, cancel, start, reset] = useTimeoutControlledFn(fn, defaultMs?: number);
  • isReady() → returns true | false | null
  • cancel() → cancels the current timeout
  • start(delay?) → starts a new timeout
  • reset() → reuses last delay

Example

const [isReady, cancel, start, reset] = useTimeoutControlledFn(() => {
  console.log('Executed after delay!');
}, 1500);

// Manually start after a successful API call
const onApiSuccess = () => start();

If this sounds useful, I’m happy to prepare a full PR with tests and docs. Just wanted to get your feedback first

muradsofi avatar Jul 25 '25 15:07 muradsofi

Also (maybe?) if useTimeoutControlledFn is introduced, it could be reused internally by both useTimeoutFn and useTimeout to simplify the implementation and keep things consistent.

For example:

// useTimeout.ts
import useTimeoutFn from './useTimeoutFn';
import useUpdate from './useUpdate';

export default function useTimeout(ms: number = 0) {
  const update = useUpdate();
  return useTimeoutFn(update, ms);
}
// useTimeoutFn.ts
import useTimeoutControlledFn from './useTimeoutControlledFn';

export default function useTimeoutFn(fn: Function, ms: number = 0) {
  const [isReady, cancel, start] = useTimeoutControlledFn(fn, ms);

  useEffect(() => {
    start();
    return cancel;
  }, [ms]);

  return [isReady, cancel, start];
}

So even though it's a new hook, it could act as the base logic and reduce duplication across the others. Let me know if that sounds good. I’d be happy to refactor and include those changes in a PR as well.

muradsofi avatar Jul 25 '25 15:07 muradsofi