【问题标题】:React state not updating inside setInterval反应状态没有在 setInterval 内更新
【发布时间】:2021-01-21 00:34:47
【问题描述】:

我正在尝试通过一些简单的项目来学习 React,但似乎无法理解以下代码,因此希望得到解释。

这个来自简单倒计时功能的 sn-p 工作正常;但是,当我使用 console.log 时,setTime 似乎正确更新了“秒”的值,但是当我在 console.log(time) 之后立即给我原始值 3。这是为什么呢?

奖励问题 - 当函数 startCountdown 被调用时,我的 JSX 中出现的正确时间值会有延迟,我认为这是由于变量“秒”被填充和 setInterval 函数的开始,所以我不倒计时不能顺利准确地开始。有没有办法解决这个问题?

const [ time, setTime ] = useState(3);
const [ clockActive, setClockActive ] = useState(false);

  
  function startCountdown() {
    let seconds = time * 60;
    setClockActive(true);
    let interval = setInterval(() => {
      setTime(seconds--);
      console.log(seconds); // Returns 179
      console.log(time); // Returns 3
        if(seconds < 0 ) {
        clearInterval(interval);
      }
    }, 1000)
  };

【问题讨论】:

标签: reactjs


【解决方案1】:

更新: 您在函数中没有看到正确值的原因是 setState 发生的方式(setTime)。当您调用 setState 时,它​​会分批调用并在需要时在 后台 中执行它们。所以你不能调用 setState 然后立即期望能够在函数内部使用它的值。

你可以把console.log从函数里拿出来,放到render方法里,你就会看到正确的值了。

或者你可以试试这样的useEffect。

//这意味着每当你使用setTime并且组件被更新时,打印当前的时间值。仅在时间变化时执行此操作。

useEffect(()=>{
   console.log(time);
},[time]);

每次你 setState 时,你都会重新渲染组件,这会对状态造成严重破坏。因此,在您的 setInterval 内的每一秒,您都在重新渲染组件并在您已经运行的内容之上重新启动它。要解决此问题,您需要使用 useEffect 并传入您正在使用的状态变量。我在这里为你做了一个例子:

https://codesandbox.io/s/jolly-keller-qfwmx?file=/src/clock.js

import React, { useState, useEffect } from "react";
const Clock = (props) => {
  const [time, setTime] = useState(3);
  const [clockActive, setClockActive] = useState(false);

  useEffect(() => {
    let seconds = 60;

    setClockActive(true);
    const interval = setInterval(() => {
      setTime((time) => time - 1);
    }, 1000);

    if (time <= 0) {
      setClockActive(false);
      clearInterval(interval);
    }
    return () => {
      setClockActive(false);
      clearInterval(interval);
    };
  }, [time, clockActive]);

  return (
    <>
      {`Clock is currently ${clockActive === true ? "Active" : "Not Active"}`}
      <br />
      {`Time is ${time}`}
    </>
  );
};
export default Clock;

【讨论】:

    猜你喜欢
    • 2021-04-29
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    相关资源
    最近更新 更多