课程章节: 第6章 更上一层楼 - 完成 Menu 组件
主讲老师:张轩
课程内容:
今天学习的内容包括:
6-10 完美组件 - SubMenu 组件添加测试
课程收获:
React Hook中useState更新延迟
错误实例
const[zoom, setZoom] = useState(0);
useEffect(() = >{
document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
},[]);
function scrollFunc(e) {
setZoom(zoom + 5)
}
会出现zoom永远等于 0+5, 而不是所谓的5, 10 ,15 为什么会这样呢? 因为useEffect执行时,会创建一个闭包,在每次监听到mousewheel运行时 闭包内部保存了zoom的初始化值 每次调用的时候都是取的初始化值0 所有会一直为0+5
怎么解决呢?
解决方案: 去掉useEffect中的空数组即可
const[zoom, setZoom] = useState(0);
useEffect(() = >{
document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
return () = >document.getElementById('workspace-content').removeEventListener("mousewheel", scrollFunc); // 记得解绑事件
});
function scrollFunc(e) {
setZoom(zoom + 5)
}
方法二:将改变函数移入useEffect并将第二个参数设置为state
依旧用上面的例子
解决方法:正确示例
useEffect(() = >{
document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
return () = >document.getElementById('workspace-content').removeEventListener("mousewheel", scrollFunc);
function scrollFunc(e) {
setZoom(zoom + 5) e.preventDefault()
}
},[zoom]);
方法三:使用Ref, 在useEffect内监听此ref, 并实时跟useState同步
例如下面的代码 错误示例
const [currentIndex, setCurrentIndex] = useState(0)
const handleLeft = () => {
setCurrentIndex(currentIndex+ 1)
console.log(currentIndex)
}
初始化currentIndex为0 每次执行handleLeft函 数是让currentIndex加1, 之后立即获取currentIndex的值发现 第一次执行currentIndex = 0
第二次执行currentIndex = 1 每次都跟实际情况差一个 查阅资料发现useState必须要执行完react整个生命周期才会获取最新值
解决方案:用useRef中转,并实时同步给useState
const [currentIndex, setCurrentIndex] = useState(0)
const currentIndexRef = useRef(0);
const handleLeft = () => {
currentIndexRef.current += 1
console.log(currentIndexRef.current)
}
useEffect(()=>{
setCurrentIndex(currentIndexRef.current)
},[currentIndexRef.current])
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦