Zustand中数组扁平化失效?品牌收藏列表更新异常问题
问题解决:品牌收藏列表更新逻辑错误导致数组嵌套
我有一个品牌列表数组,每个品牌对象包含品牌名称和products字段。首次添加新品牌对象时功能正常,但后续添加新品牌并保留原有品牌数据时,结果不符合预期(当前效果是数组嵌套,预期是平级的品牌列表)。我试过用flat()但没用,相关代码如下:
import create from "zustand"; import {persist} from "zustand/middleware"; import {zustandStorage} from "../utils/Storage"; export const useFavoritesStore = create( persist( set => ({ brandsFavoritesList: [], updateFavList: brandData => { set(state => ({ brandsFavoritesList: // 检查列表中是否已有品牌 state.brandsFavoritesList.length > 0 ? state.brandsFavoritesList.map(brand => // 如果品牌已存在,合并产品 brand.tenant === brandData?.tenant ? { ...brand, products: [...brand.products, ...brandData.products], } : // 问题出在这里:每次循环都返回整个列表加新品牌 [...state.brandsFavoritesList, brandData].flat(), ) : [...state.brandsFavoritesList, {...brandData}], })); }, }), { name: "favorites-local", getStorage: () => zustandStorage, }, ), );
问题根源
你这段代码的核心错误在于updateFavList的逻辑:当列表已有品牌且当前要添加的品牌不存在时,你在map的每个循环项里都返回[...state.brandsFavoritesList, brandData],这会让原有列表的每个品牌都被替换成一个包含所有旧品牌加新品牌的数组,最终整个brandsFavoritesList变成多层嵌套结构,flat()根本无法修复逻辑错误带来的问题。
修复方案
正确的逻辑应该是:先判断列表中是否存在目标品牌,存在则合并该品牌的products,不存在则将新品牌追加到列表末尾。修改后的代码如下:
import create from "zustand"; import { persist } from "zustand/middleware"; import { zustandStorage } from "../utils/Storage"; export const useFavoritesStore = create( persist( (set) => ({ brandsFavoritesList: [], updateFavList: (brandData) => { set((state) => { // 快速定位列表中是否存在同tenant的品牌 const targetIndex = state.brandsFavoritesList.findIndex( (brand) => brand.tenant === brandData?.tenant ); if (targetIndex !== -1) { // 存在则更新对应品牌的products数组 const updatedList = [...state.brandsFavoritesList]; updatedList[targetIndex] = { ...updatedList[targetIndex], products: [ ...updatedList[targetIndex].products, ...brandData.products, ], }; return { brandsFavoritesList: updatedList }; } else { // 不存在则直接追加新品牌到列表 return { brandsFavoritesList: [...state.brandsFavoritesList, brandData], }; } }); }, }), { name: "favorites-local", getStorage: () => zustandStorage, } ) );
修复说明
- 用
findIndex快速定位目标品牌,比遍历map更高效直接 - 存在目标品牌时,复制原数组并替换对应位置的品牌对象,合并新旧
products数组 - 不存在目标品牌时,直接将新品牌追加到原数组末尾,保证列表始终是平级的品牌对象数组
这样不管是给已有品牌添加产品,还是新增品牌,都能得到预期的平级列表结构。
内容的提问来源于stack exchange,提问作者Oliver D
相关产品推荐
相关产品推荐

