React在定时器中无法获取状态最新值的问题
短信预约 -IT技能 免费直播动态提醒
在定时器中无法获取状态最新值
在做轮播图组件时发现了一个问题,在setInterval中无法通过状态直接获取最新值,如:
const [rightTransform, setRightTransform] = useState(pictureSize);
const autoPlay = () => { //普通轮播自动播放
timer.current = setInterval(() => {
let oldState = rightTransform;
console.log('老状态', oldState) //始终只会打印初始的pictureSize
setRightTransform(o => {
const newState = JSON.parse(JSON.stringify(o));
return newState >= (renderImgList.length) * pictureSize ? 0 : newState + pictureSize
})
}, 1000);
}
问题原因
定时器一直都没有被清除,因此获取的状态始终是定时器被创建时候的状态。
问题解决
从代码和图片可以看到,定时器中打印的状态永远都是初始值,后面所改变的值虽然更新了,页面也发生了变化,但是我们从log中无法获取到实时状态。
解决办法很简单:
第一种,就是在setState中获取上一次状态,因为useState hooks提供了记录上一次状态的缓存回调,可以在这个回调中获取上一轮状态
如图:
timer.current = setInterval(() => {
let oldState = rightTransform;
setRightTransform(o => {
console.log('在setState中的老状态', o)
const newState = JSON.parse(JSON.stringify(o));
return newState >= (renderImgList.length) * pictureSize ? 0 : newState + pictureSize
})
console.log('直接打印老状态', oldState)
}
ReactHook hooks和定时器产生的bug
问题1
使用定时器改变state,state的值并不是最新值
例:
const _onClick = function ()
{
setInterval(() => {
console.log(value);
setValue(value + 1);
},1000)
}
产生原因:因为每次setValue后会重新创建函数,由于并没有及时清理掉setInterval,setInterval执行的上下文环境都是第一次创建本函数式组件的上下文(所以value值不会超过1)
解决方案
方案一:
setInterval(() => {
console.log(value);
setValue(v=>v+1); 函数式的setValue会保存上一次的值,所以会取得最新值,该方式指定state该如何改变而不用引用当前state
},1000)
方案二:
useEffect(() => {
const id = setInterval(() => {
valf.current++; 不一定是ref操作,正常set操作即可
}, 1000);
return () => clearInterval(id);
}, []);
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341