反应状态没有在 SetInterval 方法中正确更新
Posted
技术标签:
【中文标题】反应状态没有在 SetInterval 方法中正确更新【英文标题】:React State not getting updated properly in SetInterval Methods 【发布时间】:2021-04-29 23:18:32 【问题描述】:我在 UI 和 OnClick 事件处理程序中有一个按钮,我必须运行一个设置间隔计时器。在设置间隔计时器中,我正在检查条件,如果满足条件,我正在更新状态,但它不能正常工作。
import React, useState, useEffect, useRef from "react";
import ReactDOM from "react-dom";
function Counter()
let [count, setCount] = useState(0);
let [gg, setgg] = useState(false);
function countdownTimer()
console.log(count + gg.toString());
if (count > 10)
setgg(true);
setCount((count) => count + 1);
function handleClick()
let id = setInterval(countdownTimer, 1000);
return (
<div>
<button onClick=handleClick>Click</button>
<h1>count + gg.toString()</h1>
</div>
);
const rootElement = document.getElementById("root");
// Second interval to demonstrate the issue.
// Fast updates from it cause the Counter's
// interval to constantly reset and never fire.
setInterval(() =>
ReactDOM.render(<Counter />, rootElement);
, 1
00);
在 countdownTimer 函数中有一个 console.log,它总是打印“0 false”,但 UI 中的组件正在更新为正确的数字。
请告诉我为什么
-
console.log 中的计数始终为“0”
如果计数始终为零,如何正确更新状态?
如何在 countdowntimer 函数的 console.log() 中打印正确的计数值。
代码沙盒链接:https://codesandbox.io/s/dank-grass-7o4ms?file=/src/index.js
组件更新正确但console.log始终为零的屏幕截图。
【问题讨论】:
【参考方案1】:问题
console.log 中的计数始终为“0”
陈旧的count
状态包含在updfun
回调中。
如果计数始终为零,如何正确更新状态?
您使用了功能状态更新,因此每次更新都正确地从前一个状态更新,不是回调入队时的状态。
如何在 countdowntimer 函数的 console.log() 中打印正确的计数值。
使用useEffect
在更新时发出日志记录状态的副作用,并检查count
是否大于10
以设置gg
状态。
function Counter()
const [count, setCount] = useState(0);
const [count, setCount] = useState(0);
const [gg, setgg] = useState(false);
useEffect(() =>
console.log(count + gg.toString());
if (count > 10)
setgg(true);
, [count, gg]);
useEffect(() => () => clearInterval(timerRef.current), []);
function updfun()
setCount((count) => count + 1);
function handleClick()
timerRef.current = setInterval(updfun, 1000);
return (
<div>
<button onClick=handleClick>Click</button>
<h1>count + gg.toString()</h1>
</div>
);
【讨论】:
陈旧状态是什么意思?你能解释一下吗? @Ravi 啊,我一直认为“陈旧状态”这个词是不言自明的。基本上count
的值在渲染周期中被关闭(参见Closures),回调被保存在setInterval
中。可以将其视为创建间隔并一遍又一遍地调用时的状态的“快照”。【参考方案2】:
您需要先设置 count
值,然后将其更新为状态,以便您的 countdounTimer
应该像
function countdownTimer()
console.log(count + gg.toString());
if (count > 10)
setgg(true);
setCount(++count);
或
function countdownTimer()
console.log(count + gg.toString());
if (count > 10)
setgg(true);
count=count+1
setCount(count);
Click Here 用于演示
【讨论】:
这只“有效”,因为你正在改变(++count
和count += 1
)状态对象,这在 React 中是一个非常糟糕的习惯。 Using State Correctly以上是关于反应状态没有在 SetInterval 方法中正确更新的主要内容,如果未能解决你的问题,请参考以下文章