[英]React component reacts unexpectedly
The following is a simple react component:下面是一个简单的反应组件:
import React from "react";
import { useState } from "react";
export default function Comp() {
let [count, setCount] = useState(1);
function countUp(){
setCount(count + 1);
}
setInterval(countUp, 1000);
return <h2>{count}</h2>
}
I expected the counter to go up every second But for some reason, after ten - twenty seconds something starts to go wrong我预计计数器每秒都会上升但是出于某种原因,十到二十秒后开始出现问题
See here: https://stackblitz.com/edit/react-az7qgn?file=src/comp.jsx见这里: https : //stackblitz.com/edit/react-az7qgn?file=src/comp.jsx
Can anyone explain this?谁能解释一下?
You should use useEffect
hook to set up that properly.您应该使用
useEffect
钩子来正确设置。 I can provide an example.我可以提供一个例子。
import React, { useState, useEffect } from "react";
export default function Comp() {
const [count, setCount] = useState(1);
useEffect(() => {
const interval = setInterval(() => {
setCount(state => state + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <h2>{count}</h2>
}
A couple of notes.一些注意事项。
In general, you would prefer const
over let
, but this is mandatory when destructuring things coming from React.一般来说,你更喜欢
const
不是let
,但在解构来自 React 的东西时这是强制性的。
I suggest to read Using the Effect Hook on React docs to more information about useEffect
.我建议阅读Using the Effect Hook on React 文档以了解有关
useEffect
更多信息。
Basically, useEffect
allows you to achieve similar results to componentDidMount
and componentDidUpdate
lifecycle methods for class components.基本上,
useEffect
允许您获得与类组件的componentDidMount
和componentDidUpdate
生命周期方法类似的结果。 Also, in this specific case, by returning a function in useEffect
callback, we make sure to clear the scheduled callback when it's time to clean up, which means after each run.此外,在这种特定情况下,通过在
useEffect
回调中返回一个函数,我们确保在需要清理时清除计划的回调,这意味着在每次运行之后。 This actually avoids the mess of stacking many setInterval
on top of each other.这实际上避免了将许多
setInterval
堆叠在一起的混乱情况。
Also, when you setCount
it's preferable to get the previous state by using the callback form, because that will be always up-to-date.此外,当您
setCount
,最好使用回调表单获取先前的状态,因为这将始终是最新的。
When calling setInterval(), it returns an interval id.当调用 setInterval() 时,它返回一个间隔 id。 Your code is not saving the variable, and thus you cannot reset it.
您的代码没有保存变量,因此您无法重置它。 On smaller iterations, you will not see the changes for every iteration.
在较小的迭代中,您不会看到每次迭代的变化。 But, as the number of times that setInterval() is called increases from 0 to N, more timers are being initiated, and you will rapidly see flashes of numbers as they increase, because every interval is changing the state of
count
.但是,随着 setInterval() 被调用的次数从 0 增加到 N,更多的计时器被启动,随着数字的增加,你会很快看到数字闪烁,因为每个间隔都在改变
count
的状态。
In other words, you are creating more and more timers as time goes on, rather than creating timers for one-time use.换句话说,随着时间的推移,您正在创建越来越多的计时器,而不是创建一次性使用的计时器。 You will need to call
clearInterval(timer_id_goes_here)
to clear the timer.您需要调用
clearInterval(timer_id_goes_here)
来清除计时器。 See code examples in the link below.请参阅下面链接中的代码示例。
https://www.w3schools.com/jsref/met_win_setinterval.asp https://www.w3schools.com/jsref/met_win_setinterval.asp
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.