如何使用useState、Dispatch输入?

问题描述 投票:0回答:1

考虑这段代码:

const [seconds, setSeconds] = useState<number>(START_VALUE);
useEffect(() => {
  const intervalId = setInterval(() => {
    setSeconds((previousSeconds) => previousSeconds - 1);
  }, 1000);
  if(seconds <= 0) {
      clearInterval(intervalId);
      functionX();
  }
  return () => clearInterval(intervalId);
} 
}, [seconds]);

上述代码的问题是,每秒都会触发

useEffect
,有没有办法访问
setSeconds
计算中的值以在
setInterval
内部使用?

reactjs react-hooks timer setinterval countdown
1个回答
0
投票

setInterval 调用在 useEffect 中打开。每次状态发生变化时都会调用它。因此它是无限的。

请为 setInterval 添加条件,以便仅调用一次。由于它是调度代码,因此应该只调用一次。一旦安排好,它就会自动按照时间表运行。

为了为 setInterval 设置条件,请使用 ref,如下面的代码所示。如您所知,即使在渲染后,Ref 仍将保留其值。因此,这里将是一个理想的选择。 有关 refs 的更多信息,请参阅此处 何时使用 refs

不需要 useEffect 的清理代码,因为 useEffect 中的自定义代码会处理它。清除设定的间隔。

App.js

import { useState, useEffect, useRef } from 'react';

const START_VAL = 3;

export default function App() {
  const [seconds, setSeconds] = useState(START_VAL);
  const intervalId = useRef(0);

  useEffect(() => {
    if (intervalId.current == 0) {
      intervalId.current = setInterval(() => {
        setSeconds((previousSeconds) => previousSeconds - 1);
      }, 1000);
    } else if (seconds === 0) {
      clearInterval(intervalId.current);
    }
  }, [seconds]);
  return `${seconds} of ${START_VAL} seconds`;
}

试运行

组件总共渲染了4次。

// 3 of 3 seconds
// 2 of 3 seconds
// 1 of 3 seconds
// 0 of 3 seconds
© www.soinside.com 2019 - 2024. All rights reserved.