3 回答
![?](http://img1.sycdn.imooc.com/545868cd00013bbb02200220-100-100.jpg)
TA贡献1942条经验 获得超3个赞
当我们设置状态时,功能组件会从上到下重新执行,但是当我们使用 useState、useCallbacks 等时,它们不会重新初始化为变量、函数、
所以在这种情况下,setInterval
将重新初始化每个setCount
,因为状态发生了变化,
一步步
在第 1 秒会有一个 setInterval,调用 setCount 组件准备好重新渲染
重新渲染时,开始从上到下执行它再次看到的功能组件,
setInterval
它会触发它,所以现在我们有两个setIntervals
所以它会在每一秒添加多个setIntervals,因为我们没有清除它,所以你应该看到浏览器中打印的数字不会花费一秒钟,但随着时间的推移会不到一秒钟。
您可以在不清除每次重新渲染的先前间隔的情况下获得预期结果,useEffect
这是由于setCount
创建一个变量来保存设置的间隔,代码
const interval = null;
//this should be declare out side the component,
//because if we declare it inside the component it will redeclare,
//and the reference to the previous setInterval will be lost in that case no-way to clear the setInterval.
export default function IncorrectDependency() {
....
if (interval) {
clearInterval(interval);
}
interval = setInterval(inc, 1000);
....
}
或者 React 有一个钩子,它可以保存相同的变量而无需在每个渲染上重新初始化,
const intvl = useRef(null);
....
if (intvl?.current) {
clearInterval(intvl.current);
}
intvl.current = setInterval(inc, 1000);
.....
![?](http://img1.sycdn.imooc.com/5333a1bc00014e8302000200-100-100.jpg)
TA贡献1876条经验 获得超7个赞
当您直接使用 setInterval 时发生了什么,因为这是一个函数,它将在状态更改时被调用,因此将再次触发 setInterval 等等,这实际上会给您不正确的结果,因此您不应该在没有使用效果的情况下使用 setInterval,也在卸载时你应该清除间隔
![?](http://img1.sycdn.imooc.com/545861b80001d27c02200220-100-100.jpg)
TA贡献1860条经验 获得超9个赞
Dan Abramov 解释了为什么这不是一个好主意:
“这不是惯用的方法。例如,如果您有同一组件的多个实例,它将无法正常工作。它违反了规则——它在渲染过程中产生了副作用(setInterval),页面上说你不应该这样做做 :) 一旦你违反了规则,所有的赌注都取消了”
添加回答
举报