我正在试用新的 React Hooks并有一个带有计数器的时钟组件,该计数器应该每秒增加一次。但是,该值不会增加超过 1。
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()
没有被第二次调用。
time
在 setInterval
回调中的值始终为 0。
和你熟悉的setState
一样,state hooks有两种形式:一种是获取更新后的状态,另一种是传入当前状态的回调形式。你应该使用第二种在 setState
回调中形成并读取最新的状态值,以确保您在递增之前拥有最新的状态值。
Bonus: Alternative Approaches
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>
关于javascript - 在 setInterval 中使用 React 状态 Hook 时状态不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53024496/