0

I created this hook that is responsible to do something after an amount of time:

const useTime = (callback, timeout = 1000) => {
    useEffect(() => {
        const timer = setTimeout(() => {
            callback()
        }, timeout);
        return () => clearTimeout(timer);
    }, []);
}

The hook is working, but i can not call it inside a method like:

  {        
  clear: () => {
    useTime(() => console.log('close'), 6000 )
  },

... this is happen because of hooks rules.
Question: How to refactor the hook to be able to call it inside a method or a function?

Asking
  • 3,487
  • 11
  • 51
  • 106

2 Answers2

0

You probably need to do like this -

function useTime(cb, timeout = 100) {
  const timer = setTimeout(() => {
     cb();
  }, timeout);

  return () => clearTimeout(timer);
}

function anotherMethod() {
  const cancel = useTime(runJob, 1000);
  
  // if you wanna cancel the timer, just call the cancel function
  cancel();
}

xencodes
  • 39
  • 2
  • 5
  • runJob could not be every time global, but it could be a parameter from a function for example. – Asking Sep 07 '22 at 18:05
0

You can try something around this:

const useTime = () => {
    const timer = useRef();
    const fn = useCallback((callback, timeout = 1000) => {
      timer.current = setTimeout(() => {
        callback()
      }, timeout);
    }, []);

    useEffect(() => {
        return () => clearTimeout(timer.current);
    }, []);

    return fn;
}
  const delayedFn = useTime();

  clear: () => {
    delayedFn(() => console.log('close'), 6000)
  },

Edit crimson-water-7i9etg

Fraction
  • 11,668
  • 5
  • 28
  • 48
  • it works, but when i try to add this: const [state, setState] = useState(''); const delayedFn = useTime(); const handleClick = () => { setState('start') delayedFn(() => console.log("close", state), 6000); }; , i don't het in updated state in delayedFn. How to do that? Do i need a dependancy? – Asking Sep 07 '22 at 17:53
  • The state will be updated in the next render so you must use `useEffect`: ```useEffect(() => { delayedFn(() => console.log("close", state), 6000); }, [state])``` – Fraction Sep 07 '22 at 18:13
  • But how to get the result in handleClick function? – Asking Sep 07 '22 at 19:12
  • You can't, you have to use the same value you passed to `setState`: `console.log("close", 'start')` or use `useEffect` as above, more info [here](https://stackoverflow.com/q/54069253/11129751) – Fraction Sep 08 '22 at 09:21