如何用Redux Toolkit实现购物车项的LocalStorage存储与刷新后读取
解决页面刷新后恢复购物车数据及商品移除逻辑
一、页面刷新后恢复购物车数据
你的核心问题是初始化Redux state时没有从localStorage读取已保存的购物车数据,导致刷新后state重置为空。另外,localStorageItems字段完全多余,直接用items同步localStorage即可。
修改Reducer初始化逻辑
先写一个工具函数,从localStorage加载购物车数据并计算初始的totalQuantity:
// 从localStorage加载购物车数据并计算总数量 const loadCartFromLocalStorage = () => { const savedCart = localStorage.getItem("list"); if (savedCart) { const items = JSON.parse(savedCart); // 计算所有商品的总数量 const totalQuantity = items.reduce((sum, item) => sum + item.quantity, 0); return { items, totalQuantity }; } // 没有数据时返回初始空状态 return { items: [], totalQuantity: 0 }; }; // 修改createSlice的initialState const productItemsSlice = createSlice({ name: "product", initialState: loadCartFromLocalStorage(), // 调用加载函数初始化 reducers: { addProduct(state, action) { const newItem = action.payload; const existingItem = state.items.find((item) => item.id === newItem.id); state.totalQuantity++; if (!existingItem) { state.items.push({ id: newItem.id, price: newItem.price, quantity: 1, totalPrice: newItem.price, name: newItem.name, image: newItem.image, category: newItem.category, }); } else { existingItem.quantity += 1; existingItem.totalPrice += newItem.price; } // 只需要将更新后的items保存到localStorage即可 localStorage.setItem("list", JSON.stringify(state.items)); }, // 后续添加移除商品的reducer }, });
修改组件读取逻辑
直接从state.productItem.items获取数据,不再需要localStorageItems:
const productItems = useSelector((state) => state.productItem.items); const items = productItems.map((el) => { return ( <CartItems key={el.id} item={{ id: el.id, name: el.name, image: el.image, price: el.price, category: el.category, totalPrice: el.totalPrice, quantity: el.quantity, }} /> ); });
二、移除购物车商品的处理逻辑
添加一个removeProduct reducer,处理两种场景:商品数量大于1时减少数量,数量等于1时直接删除该商品,同时同步更新totalQuantity和localStorage。
在reducers中添加removeProduct方法
const productItemsSlice = createSlice({ // ... 其他代码不变 reducers: { // ... addProduct方法不变 removeProduct(state, action) { const itemId = action.payload; const existingItem = state.items.find((item) => item.id === itemId); if (!existingItem) return; // 总数量减1 state.totalQuantity--; if (existingItem.quantity > 1) { // 数量大于1时,减少数量并更新总价 existingItem.quantity -= 1; existingItem.totalPrice -= existingItem.price; } else { // 数量等于1时,从数组中删除该商品 state.items = state.items.filter((item) => item.id !== itemId); } // 同步更新localStorage localStorage.setItem("list", JSON.stringify(state.items)); }, }, }); // 导出removeProduct action export const { addProduct, removeProduct } = productItemsSlice.actions;
在组件中使用removeProduct
在<CartItems>组件中,绑定移除按钮的点击事件,调用dispatch(removeProduct(item.id))即可:
import { useDispatch } from 'react-redux'; import { removeProduct } from './path-to-your-slice'; const CartItems = ({ item }) => { const dispatch = useDispatch(); return ( <div> {/* 商品信息展示 */} <button onClick={() => dispatch(removeProduct(item.id))}>移除一件</button> </div> ); };
内容的提问来源于stack exchange,提问作者Mohit
相关产品推荐
相关产品推荐

