React Context结合LocalStorage刷新后数据不持久问题排查
解决React Context结合LocalStorage刷新后数据丢失的问题
你的问题出在初始渲染的执行顺序上:
- 组件挂载时,
useState先把products初始化为空数组 - 紧接着触发监听
products变化的useEffect,把空数组写入LocalStorage,直接覆盖了之前存储的数据 - 之后读取LocalStorage的
useEffect才执行,但此时LocalStorage已经被清空,读不到有效数据
修复方案
直接在useState的初始化阶段读取LocalStorage,而不是依赖额外的useEffect。useState的初始化函数只会在组件首次挂载时执行一次,完美避开覆盖问题。
修改后的核心代码:
function CartProvider({ children }: { children: ReactNode }) { // 直接在useState初始化时读取LocalStorage const [products, setProducts] = useState<CartProduct[]>(() => { const savedCart = localStorage.getItem("cart"); return savedCart ? JSON.parse(savedCart) : []; }); // 只保留写入LocalStorage的useEffect useEffect(() => { localStorage.setItem("cart", JSON.stringify(products)); }, [products]); // addProduct和removeProduct逻辑保持不变 function addProduct(product: Product) { const existingProduct = products.find((p) => p.id === product.id); if (existingProduct) { const updatedProducts = products.map((p) => { if (p.id === product.id) { return { ...p, quantity: p.quantity + 1 }; } else { return p; } }); setProducts(updatedProducts); } else { const newProduct = { ...product, quantity: 1 } as CartProduct; const updatedProducts = [...products, newProduct]; setProducts(updatedProducts); } } function removeProduct(product: Product) { const existingProduct = products.find((p) => p.id === product.id); if (existingProduct && existingProduct.quantity > 1) { const updatedProducts = products.map((p) => { if (p.id === product.id) { return { ...p, quantity: p.quantity - 1 }; } else { return p; } }); setProducts(updatedProducts); } else { const updatedProducts = products.filter((p) => p.id !== product.id); setProducts(updatedProducts); } } const cartContextValue = { products, addProduct, removeProduct }; return ( <CartContext.Provider value={cartContextValue}> {children} </CartContext.Provider> ); }
额外注意事项
- 如果你的
Product类型包含无法被JSON.stringify序列化的字段(比如Date对象、函数),需要先处理这些字段再存入LocalStorage,否则会丢失数据 - 若项目涉及服务端渲染(SSR),需要用
typeof window !== 'undefined'包裹LocalStorage操作,避免在服务端执行时报错
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

