首页 > 解决方案 > 反应:使用间隔不清除

问题描述

useInterval一旦joke数组有 5 个笑话作为对象,我就会尝试清除该函数。但是,我不确定我做错了什么。完整代码:https ://codesandbox.io/s/asynchronous-test-mp2fq?file=/AutoComplete.js

 const [joke, setJoke] = React.useState([]);

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

    let id;

    useEffect(() => {
      savedCallback.current = callback;
      if (joke.length === 5) {
        console.log("5 STORED AND CLEARED INTERVAL");
        return () => clearInterval(id);
      }
    });

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

      id = setInterval(tick, delay);
      return () => clearInterval(id);
    }, [delay]);
  }

  useInterval(() => {
    // setJoke(joke);
    axios.get("https://api.chucknorris.io/jokes/random").then((res) => {
      setJoke(joke.concat(res.data.value));
      console.log("JOKE: ", joke);
    });

    console.log("Every 5 seconds");
  }, 5000);

在此处输入图像描述

标签: javascriptreactjsreact-hooksintervals

解决方案


使用 ref 存储间隔 id,以在重新渲染之间保留它。当长度为 5 时,调用clearInterval而不是返回将在组件卸载时调用的干净函数。

此外,通过提供一个stop函数并在组件重新渲染时调用它,使钩子与实际停止条件无关。

function useInterval(callback, delay, stop) {
  const savedCallback = useRef();
  const interval = useRef();

  useEffect(() => {
    savedCallback.current = callback;
    
    if (stop?.()) { // call stop to check if you need to clear the interval
      clearInterval(interval.current); // call clearInterval
    }
  });

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

    interval.current = setInterval(tick, delay); // set the current interval id to the ref

    return () => clearInterval(interval.current);
  }, [delay]);
}

const Example () => {
  const [joke, setJoke] = React.useState([]);
  
  useInterval(() => {
    // setJoke(joke);
    axios.get("https://api.chucknorris.io/jokes/random").then((res) => {
      setJoke(joke.concat(res.data.value));
      console.log("JOKE: ", joke);
    });

    console.log("Every 5 seconds");
  }, 5000, () => joke.length > 4);
  
  return (
    ...
  );
};

推荐阅读