【问题标题】:Why does useState update in DOM but not in console?为什么 useState 在 DOM 中更新,但在控制台中没有?
【发布时间】:2022-10-13 19:27:17
【问题描述】:

我在这里有点困惑,如果有人能解释为什么useState 表现出这种行为,我将不胜感激。我有一个使用 useState 的功能组件,它启动一个计时器并在 DOM 中实时正确地呈现时间。停止计时器后,我想将时间推送到一个数组,但每次尝试都只是推送 0 - time 变量的初始状态。

经过一些调试后,我注意到如果我 console.log() 间隔循环函数内的时间它也会继续记录 0,而不是“真实”时间。

这是我的代码。我已经删除了与手头问题无关的所有部分。

export default function Timer() {
    const [time, setTime] = useState(0);
    const interval = useRef(null);

    clearInterval(interval.current);
    let startTime = Date.now() - time;
    interval.current = setInterval(() => {
        setTime(Date.now() - startTime);            
        console.log(time); // <-- Why does this continue to show 0?
    }, 10);

    return (
        <div>
            <span>{("0" + Math.floor((time / 60000) % 1000)).slice(-2)}:</span>
            <span>{("0" + Math.floor((time / 1000) % 1000)).slice(-2)}.</span>
            <span>{("00" + (time % 1000)).slice(-3, -1)}</span>
        </div>
    );
}

所以我的问题是,为什么time 变量返回正确的时间实时在 DOM 内部但不在控制台中?我认为这可能是因为 useState 不是即时的,但我不明白为什么它会继续记录 0。

编辑:

我通过声明一个单独的变量curTime = 0 解决了这个问题,而不是使用setTime(Date.now() - startTime),而是使用curTime = (Date.now() - startTime):

export default function Timer() {
    const [time, setTime] = useState(0);
    const interval = useRef(null);
    let curTime = 0

    clearInterval(interval.current);
    let startTime = Date.now() - time;
    interval.current = setInterval(() => {
        curTime = (Date.now() - startTime);     
        setTime(curTime)    
        console.log(curTime); // <-- Now shows correct time.
    }, 10);

    return (
        <div>
            <span>{("0" + Math.floor((time / 60000) % 1000)).slice(-2)}:</span>
            <span>{("0" + Math.floor((time / 1000) % 1000)).slice(-2)}.</span>
            <span>{("00" + (time % 1000)).slice(-3, -1)}</span>
        </div>
    );
}

【问题讨论】:

  • 区间函数中的time 总是与最初设置的变量相同,因为区间函数是一个闭包。如果您想要最新的,则需要通过useEffect 访问它
  • 如果我包含的整个代码部分都包含在它自己的函数中,这仍然有效吗?

标签: javascript reactjs react-hooks


【解决方案1】:

React 使用声明式风格。当组件重新渲染时,状态的值会发生变化。在此之前您正在记录。

【讨论】:

  • 感谢你的回答!我读过,但如果 DOM 每 10 毫秒重新渲染一次,为什么控制台仍然显示初始值?我猜我误解了 useState 的工作原理。
猜你喜欢
  • 2022-01-21
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 2020-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多