【问题标题】:React: ClearInterval and Immediately Start AgainReact:ClearInterval 并立即重新开始
【发布时间】:2021-11-07 23:46:26
【问题描述】:

我有一个组件会触发一个计时器,该计时器每 30 秒更新一次并发出 axios 请求。它使用useRef,它设置为在触发handleStart 函数后每30 秒更新一次。


  const countRef = useRef(null);
  const lastUpdatedRef = useRef(null);
  const [lastUpdated, setLastUpdated] = useState(Date.now())

  const handleStart = () => {

    countRef.current = setInterval(() => {
      setTimer((timer) => timer + 1);
    }, 1000);

    lastUpdatedRef.current = setInterval(() => {
      setLastUpdated(Date.now());
    }, 30000);
  };

现在我有一个useEffect,每当lastUpdated 作为依赖项被触发时,它每30 秒运行一次calculate 函数:

  const firstCalculate = useRef(true);

  useEffect(() => {
    if (firstCalculate.current) {
      firstCalculate.current = false;
      return;
    }
    console.log("calculating");
    calculateModel();
  }, [lastUpdated]);

这会根据 lastUpdatedRef 每 30 秒(00:30、01:00、01:30 等)更新 calculate 函数。但是,我希望计时器在 lastUpdated 状态在其他地方被修改时重新启动(例如,如果 lastUpdated 在 00:08 被修改,下一次更新将是 00:38、01:08、01:38 等) .有没有办法做到这一点?

【问题讨论】:

标签: javascript reactjs react-hooks setinterval use-effect


【解决方案1】:

基本上听起来您只需要另一个处理程序来清除并重新启动更新lastUpdated 状态的 30 秒间隔。

例子:

const handleOther = () => {
  clearInterval(lastUpdatedRef.current);
  lastUpdatedRef.current = setInterval(() => {
    setLastUpdated(Date.now());
  }, 30000);
}

完整示例:

const calculateModel = () => console.log("calculateModel");

export default function App() {
  const countRef = React.useRef(null);
  const lastUpdatedRef = React.useRef(null);
  const [lastUpdated, setLastUpdated] = React.useState(Date.now());
  const [timer, setTimer] = React.useState(0);

  const handleStart = () => {
    countRef.current = setInterval(() => {
      setTimer((timer) => timer + 1);
    }, 1000);

    lastUpdatedRef.current = setInterval(() => {
      setLastUpdated(Date.now());
    }, 30000);
  };

  const handleOther = () => {
    clearInterval(lastUpdatedRef.current);
    lastUpdatedRef.current = setInterval(() => {
      setLastUpdated(Date.now());
    }, 30000);
  };

  const firstCalculate = React.useRef(true);

  React.useEffect(() => {
    if (firstCalculate.current) {
      firstCalculate.current = false;
      return;
    }
    console.log("calculating");
    calculateModel();
  }, [lastUpdated]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      <div>Timer: {timer}</div>

      <button type="button" onClick={handleStart}>
        Start
      </button>
      <button type="button" onClick={handleOther}>
        Other
      </button>
    </div>
  );
}

当组件卸载时不要忘记清除任何运行间隔!

React.useEffect(() => {
  return () => {
    clearInterval(countRef.current);
    clearInterval(lastUpdatedRef.current);
  };
}, []);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-29
    • 2022-06-15
    • 2019-09-03
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多