单击按钮后 React hooks useInterval 重置

Jac*_*cki 5 reactjs react-hooks

我有钩子 useInterval ,它每 10 秒自动下载一次数据,但是我也有按钮,它可以每时每刻手动下载数据。当我单击按钮时,我很难重新启动间隔计时器。所以基本上,如果间隔计数到 5,但我同时单击按钮,间隔应该重新启动,并在下载数据之前再次开始计数到 ​​10

const useInterval = (callback, delay) => {
    const savedCallback = useRef(callback);

    useEffect(() => {
        savedCallback.current = callback;
    }, [callback]);

    useEffect(() => {
        const tick = () => {
            savedCallback.current();
        }

        if (delay !== null) {
            const id = setInterval(tick, delay);
            return () => clearInterval(id);
        }
    }, [delay]);
};

export default useInterval;
Run Code Online (Sandbox Code Playgroud)

应用程序部分:

useInterval(() => {
        getMessage();
      }, 10000)

const getMessage = async () => {
    setProcessing(true)
    try {
      const res = await fetch('url')
      const response = await res.json();
      setRecievedData(response)
    }
    catch (e) {
      console.log(e)
    }
    finally {
      setProcessing(false)
    }
  }

const getMessageManually = () => {
    getMessage()
    RESTART INTERVAL
  }
Run Code Online (Sandbox Code Playgroud)

Den*_*ash 5

您应该添加一个重置函数作为从挂钩返回值。

我还修复了一些问题并添加了卸载处理程序:

// Usage
const resetInterval = useInterval(() => ..., DELAY);
resetInterval(); 
Run Code Online (Sandbox Code Playgroud)
// Implementation
const useInterval = (callback, delay) => {
  const savedCallbackRef = useRef(callback);

  const intervalIdRef = useRef();

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  // handle tick
  useEffect(() => {
    const tick = () => {
      savedCallback.current();
    };

    if (delay !== null) {
      intervalIdRef.current = setInterval(tick, delay);
    }

    const id = intervalIdRef.current;
    return () => {
      clearInterval(id);
    };
  }, [delay]);

  // handle unmount
  useEffect(() => {
    const id = intervalIdRef.current;
    return () => {
      clearInterval(id);
    };
  }, []);

  const resetInterval = useCallback(() => {
    clearInterval(intervalIdRef.current);
    intervalIdRef.current = setInterval(savedCallback.current, delay)
  }, [delay]);

  return resetInterval;
};
Run Code Online (Sandbox Code Playgroud)


Mur*_*ati 5

您可以在挂钩中添加重置函数并返回该函数。重置函数应清除现有间隔并开始新的间隔。

这是可以重置和停止的钩子的代码。

const useInterval = (callback, delay) => {
  const savedCallback = useRef(callback);
  const intervalRef = useRef(null);

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  useEffect(() => {
    if (delay !== null) {
      const id = setInterval(savedCallback.current, delay);
      intervalRef.current = id;
      return () => clearInterval(id);
    }
  }, [delay]);

  useEffect(()=>{
    // clear interval on when component gets removed to avoid memory leaks
    return () => clearInterval(intervalRef.current);
  },[])

  const reset = useCallback(() => {
      if(intervalRef.current!==null){
        clearInterval(intervalRef.current);
        intervalRef.current = setInterval(savedCallback.current,delay)
      }
   });

   const stop = useCallback(() => {
      if(intervalRef.current!==null){
        clearInterval(intervalRef.current);
      }     
   })

  return {
    reset,
    stop
  };
};
    
// usage
const {reset,stop} = useInterval(()=>{},10000);
reset();
stop();
Run Code Online (Sandbox Code Playgroud)