Zustand状态管理下购物车商品列表更新同步异常问题求助
问题根因
checkProductOptionsExist逻辑完全错误- 在zustand的set回调中遍历所有购物车商品,每遍历到一个不匹配的商品就触发一次新增操作,购物车有2个已有商品时就会多生成1条重复记录
- set回调需要返回包含state字段的对象,当前返回的是map生成的数组,不符合语法规范
- 在set回调中调用其他会触发set的方法(
updateProductQuantity、addToCart),导致状态更新时序混乱,出现校验结果先true后false的异常
- 商品详情页前置校验逻辑缺陷:仅判断商品ID是否存在,没有结合规格判断,同ID不同规格的商品也会进入错误的校验流程
- 校验逻辑冗余:同时用
productOptionIds字符串和areEqual工具函数做规格校验,两处逻辑没有对齐,容易出现不一致
修复方案
1. 重写zustand Store逻辑
合并冗余的校验、新增、更新方法,直接在addToCart中完成所有判断,避免多方法调用导致的状态混乱:
interface CartProductsProp extends State { cartProducts: ProductProps[]; addToCart: (product: ProductProps) => void; ... } export const useCartProduct = create<CartProductsProp>( persist( (set, get) => ({ cartProducts: [], addToCart: (product) => { set((prev) => { // 查找是否已有同ID同规格的商品 const existProductIndex = prev.cartProducts.findIndex(cartProduct => cartProduct.id === product.id && areEqual(cartProduct.selectedOptions, product.selectedOptions) ) // 已有对应商品,累加数量 if (existProductIndex > -1) { const newCart = [...prev.cartProducts] const target = newCart[existProductIndex] newCart[existProductIndex] = { ...target, quantity: target.quantity + product.quantity, productTotalPrice: (target.quantity + product.quantity) * target.price, updated: 'yes@' } return { cartProducts: newCart } } // 没有对应商品,新增条目 return { cartProducts: [...prev.cartProducts, {...product}] } }) }, // 其他原有方法可保留,不需要再用到checkProductOptionsExist ... }), { name: 'cartListProduct-local', getStorage: () => AsyncStorage, }, ), )
2. 简化商品详情页逻辑
删除原有冗余的前置判断,直接调用重写后的addToCart即可:
const addProductToCart = () => { let productOptionIds = allOptions .map(({id}: {id: number | string}) => id) .sort() .join(','); let currentProduct = { ...item, id: item.id, product_id: item.id, quantity: currentQuantity, price: updatedPrice, productTotalPrice: updatedPrice * currentQuantity, selectedOptions: allOptions, productOptionIds: productOptionIds, }; setAddToCartLoading(true); // 直接调用addToCart即可,内部已做所有校验 addToCart(currentProduct); Alert.alert(t('addedSuccessfully')); setAddToCartLoading(false); };
3. 可选性能优化
如果需要更高的校验性能,可将findIndex中的判断替换为cartProduct.id === product.id && cartProduct.productOptionIds === product.productOptionIds,跳过数组遍历对比的步骤。
内容的提问来源于stack exchange,提问作者Oliver D
相关产品推荐
相关产品推荐

