【问题标题】:setInterval and useState - Conditional statement using updated state within the interval?setInterval 和 useState - 在间隔内使用更新状态的条件语句?
【发布时间】:2021-04-08 01:24:19
【问题描述】:

这是有人提出的另一个问题,关于 setInterval 中的状态。

问题是为什么状态没有更新超过 1。 答案是

原因是传入 setInterval 闭包的回调只在第一次渲染中访问时间变量,在后续渲染中无法访问新的时间值,因为第二次没有调用 useEffect()。

时间在 setInterval 回调中的值始终为 0。

和你熟悉的 setState 一样,状态钩子有两种形式: 一个它接受更新状态的地方,以及回调形式 当前状态被传入。您应该使用第二种形式和 读取 setState 回调中的最新状态值以确保 在递增之前您拥有最新的状态值。

function Clock() {
      const [time, setTime] = React.useState(0);
      React.useEffect(() => {
        const timer = window.setInterval(() => {
          setTime(prevTime => prevTime + 1);    <----this line was edited which makes the counter work according to the answer provided.
        }, 1000);
        return () => {
          window.clearInterval(timer);
        };
      }, []);
    
      return (
        <div>Seconds: {time}</div>
      );
    }
    
    ReactDOM.render(<Clock />, document.querySelector('#app'));

我的问题是,是否可以在使用更新版本的时间状态的间隔内使用 if 语句?我尝试在间隔内外进行控制台日志记录,并且在间隔内计数器不更新,而在间隔内更新状态。鉴于先前的答案,这是有道理的,但是有没有办法在间隔内使用状态的更新版本?或者也许是一种解决方法?

例如,可能有一个 if 语句使用时间状态和可能具有另一个状态的模运算符,并根据计算结果播放不同的声音。

【问题讨论】:

  • 您可以查看this 以了解有关此关闭的更多信息。如果需要,您可以创建一个新的自定义挂钩 - useStateAndRef(您可以在链接帖子的另一个答案中找到示例)。

标签: reactjs


【解决方案1】:

可以在回调中使用当前的有状态值,例如:

setTime(prevTime => {
  console.log(prevTime);
  // do other stuff with prevTime?
  return prevTime + 1;
});

甚至

setTime(prevTime => {
  // do stuff with prevTime
  return prevTime; // don't change state
});

但这很奇怪。为了代码清晰起见,最好避免在 state setter 函数中产生副作用。

另一个问题是区间回调只会关闭初始状态变量,所以如果你在time之外有不同的状态,它不会在区间的setTime中更新。

如果您想做类似的事情,请考虑改用 ref,它类似于功能组件的实例变量。

const [time, setTime] = React.useState(0);
const [somethingStateful, setSomethingStateful] = useState(123);
const statefulRef = useRef(123);

然后,当somethingStateful 更新时,两者都做

setSomethingStateful(newVal);

statefulRef.current = newVal;

然后您将能够在区间回调中引用statefulRef.current 以获取最新的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 2021-07-14
    相关资源
    最近更新 更多