2

I am using a function that fetches a data from server to update a loading log table.

For this purpose I set a timeout for 15 second which is called inside the function. I need to clear this timeout on componentWillUnmount, because it modifies state and I don't need to mess with state of an unmounted component.

// LogTable is my component
const LogTable = () => {
  let timerId
  const getLoadingData = () => {
    //does something
    timerId = setTimeout(getLoadingData, 15000)
    //more code
  }

  useEffect(() => {
    return function cleanup() {
      clearTimeout(timerId)
    };
  }, []);
}

The code above doesn't work, because timerId inside the useEffect function is undefined and I don't know how to fix this.

1 Answers1

5

You should actually write it as:

  const useTimeout = (task, time) => useEffect(() => {
    const id = setTimeout(task, time)
    return () => clearTimeout(id);  
 }, []);

That can then be used as:

   useTimeout(10000, () => {
     // ... do whatever
   })

Or in your specific usecase:

  const useInterval = (task, time) => useEffect(() => {
    let id;
    (async function job() {
       await task();
       id = setTimeout(job, time);
    })();
    return () => id && clearTimeout(id);  
 }, []); 

 useInterval(1000, async () => {
   //...
 });
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151