目标
- 页面count会递增
- console里面的数会递增
const App = () => {
const [count, setCount] = useState(0)
let load = false
const onClick = () => {
setCount(count + 1)
console.log('----------------------', count)
}
useEffect(() => {
window.addEventListener('click', onClick)
return () => {
window.removeEventListener('click', onClick)
}
}, [])
return <div>{count}</div>
}
问题描述
- 页面上的count只会改变一次,即从0变为1
- console里的count则一直是0
原因分析
window.addEventListener中的函数引用一直缓存的是变量onClick第一次被赋的值, 所以count一直是0
这是因为useEffect没有设置依赖项,所以在组件渲染后就不会再发生改变
解决方案
每次Function Class因为setCount重新渲染的时候,变量onClick的值也发生变化。我们如果想使结果符合预期,就必须每次渲染后都为window绑定新的事件监听函数onClick,这个时候就要为useEffect设置依赖项,即count。这个依赖告诉useEffect,每次count状态发生改变的时候,都要执行回调,给window设置新的onClick函数
useEffect(() => {
window.addEventListener('click', onClick)
// return 表示在下次页面更新发生之前,会销毁原来绑定的旧事件监听,这样不会造成内存泄漏
return () => {
window.removeEventListener('click', onClick)
}
// 添加依赖项
}, [count])
使用场景
我们在使用监听scroll或resize的时候,会发现这个问题,
尤其是在做页面加载load more的时候。
代码
网友评论