使用localStorage持久化React state时触发无限渲染循环该如何解决?
问题原因
- 你写的第一个
useEffect没有添加依赖数组,这会导致该钩子在每一次组件渲染完成后都会被触发执行 - 每次执行该
useEffect都会调用setCart生成一个全新的Map实例赋值给cart,Map是引用类型,每次生成的实例引用地址都不同 - 第二个
useEffect监听了cart依赖,只要cart的引用发生变化就会把新值写入localStorage,同时cart更新会触发组件重渲染 - 组件重渲染后又会触发第一个无依赖的
useEffect执行,形成无限循环
修复方案
给第一个useEffect添加空依赖数组[],让它仅在组件首次挂载时执行一次,读取本地存储的初始化值即可:
useEffect(() => { localStorage.myCartState ? setCart(new Map(JSON.parse(localStorage.myCartState))) : setCart(new Map()) }, []) useEffect(() => { localStorage.myCartState = JSON.stringify(Array.from(cart.entries())); }, [cart])
优化方案
你还可以直接把初始化逻辑放到useState的初始化函数中,省去第一个useEffect,避免首次挂载时额外触发一次重渲染,性能更好:
const [cart, setCart] = useState(() => { return localStorage.myCartState ? new Map(JSON.parse(localStorage.myCartState)) : new Map() }) useEffect(() => { localStorage.myCartState = JSON.stringify(Array.from(cart.entries())); }, [cart])
内容的提问来源于stack exchange,提问作者user15779299
相关产品推荐
相关产品推荐

