在setInterval中使用React状态挂钩时状态未更新

我正在尝试新的React Hooks,并有一个带有计数器的Clock组件,该计数器应该每秒增加一次。但是,该值不会增加到超过一。

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您熟悉的状态挂钩一样,状态挂钩有两种形式:一种是处于更新状态的状态,另一种是将当前状态传入的回调形式。您应该使用第二种形式,并读取setState回调中的最新状态值以在递增之前,请确保您具有最新的状态值。

Dan Abramov setInterval在他的博客文章中深入探讨了有关使用钩子的主题,并提供了解决此问题的替代方法。强烈建议阅读!

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状态挂钩时状态未更新 的全部内容, 来源链接: utcz.com/qa/421054.html

回到顶部