State not updating when using React state hook within setInterval(在 setInterval 中使用 React 状态挂钩时状态未更新)
问题描述
我正在尝试新的 React Hooks 并有一个带有时钟组件计数器应该每秒增加一次.但是,该值不会增加超过 1.
I'm trying out the new React Hooks and have a Clock component with a counter which is supposed to increase every second. However, the value does not increase beyond one.
function Clock() {
const [time, setTime] = React.useState(0);
React.useEffect(() => {
const timer = window.setInterval(() => {
setTime(time + 1);
}, 1000);
return () => {
window.clearInterval(timer);
};
}, []);
return (
<div>Seconds: {time}</div>
);
}
ReactDOM.render(<Clock />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
推荐答案
原因是因为传入setInterval
的闭包的回调只访问了time
变量第一次渲染,它无法在后续渲染中访问新的 time
值,因为第二次没有调用 useEffect()
.
The reason is because the callback passed into setInterval
's closure only accesses the time
variable in the first render, it doesn't have access to the new time
value in the subsequent render because the useEffect()
is not invoked the second time.
time
在 setInterval
回调中的值始终为 0.
time
always has the value of 0 within the setInterval
callback.
和你熟悉的setState
一样,状态钩子有两种形式:一种是接受更新的状态,另一种是传入当前状态的回调形式.你应该使用第二种在 setState
回调中形成并读取最新的状态值,以确保在递增之前获得最新的状态值.
Like the setState
you are familiar with, state hooks have two forms: one where it takes in the updated state, and the callback form which the current state is passed in. You should use the second form and read the latest state value within the setState
callback to ensure that you have the latest state value before incrementing it.
奖励:替代方法
Dan Abramov,在他的 setInterval 的主题hooks/" rel="noreferrer">博客文章 并提供解决此问题的替代方法.强烈推荐阅读!
Dan Abramov, goes in-depth into the topic about using setInterval
with hooks in his blog post and provides alternative ways around this issue. Highly recommend reading it!
function Clock() {
const [time, setTime] = React.useState(0);
React.useEffect(() => {
const timer = window.setInterval(() => {
setTime(prevTime => prevTime + 1); // <-- Change this line!
}, 1000);
return () => {
window.clearInterval(timer);
};
}, []);
return (
<div>Seconds: {time}</div>
);
}
ReactDOM.render(<Clock />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
这篇关于在 setInterval 中使用 React 状态挂钩时状态未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 setInterval 中使用 React 状态挂钩时状态未更新
基础教程推荐
- 有没有办法使用OpenLayers更改OpenStreetMap中某些要素 2022-09-06
- 角度Apollo设置WatchQuery结果为可用变量 2022-01-01
- Karma-Jasmine:如何正确监视 Modal? 2022-01-01
- 在for循环中使用setTimeout 2022-01-01
- 在 JS 中获取客户端时区(不是 GMT 偏移量) 2022-01-01
- 当用户滚动离开时如何暂停 youtube 嵌入 2022-01-01
- 动态更新多个选择框 2022-01-01
- 悬停时滑动输入并停留几秒钟 2022-01-01
- 响应更改 div 大小保持纵横比 2022-01-01
- 我什么时候应该在导入时使用方括号 2022-01-01