如何在Redux中避免向数组添加重复值?
如何在Redux中避免向数组添加重复值?
嘿,我明白你的问题——重复点击同一个项导致收藏列表里出现重复条目,还引发了key冲突的问题对吧?其实核心就是每次添加前没检查这个项是不是已经在列表里了,咱们一步步解决它。
首先,在Redux Reducer里做重复校验(最可靠的方式)
你的reducer现在是直接把新项推到数组里,完全没做检查。咱们可以在addFavorite里先判断当前项的id是否已经存在于selectedFavorites中,只有不存在的时候才添加:
const initialState = { selectedFavorites: [], }; // 修改后的addFavorite reducer逻辑 addFavorite: (state, action) => { // 用some方法检查是否已有相同id的项 const isAlreadyAdded = state.selectedFavorites.some(item => item.id === action.payload.id); // 如果已经存在,直接返回原状态,不做任何修改 if (isAlreadyAdded) { return state; } // 不存在的话,再把新项加入数组 return { ...state, selectedFavorites: [...state.selectedFavorites, action.payload], }; },
为什么你用Set没成功?
估计你之前是直接把整个对象放进Set里了吧?因为Set对引用类型(比如对象)是按引用地址判断是否重复的——哪怕两个对象的id和内容完全一样,只要是新建的对象,Set就会认为它们是不同的。
如果想用Set解决,得先提取所有已有的id存进Set,再判断新项的id是否在里面:
addFavorite: (state, action) => { const existingIds = new Set(state.selectedFavorites.map(item => item.id)); if (existingIds.has(action.payload.id)) { return state; } return { ...state, selectedFavorites: [...state.selectedFavorites, action.payload], }; },
组件里的逻辑也得同步调整
你现在的handlePress不管项是不是已经收藏,都会触发addFavorite,而且还加了个setTimeout把favorite设回false,这很容易导致组件状态和Redux状态不一致。咱们改一下:
先从Redux里获取当前的收藏列表,判断当前项是否已收藏:
// 假设你的reducer叫favoriteReducer,根据实际情况调整 const selectedFavorites = useSelector(state => state.favoriteReducer.selectedFavorites); const isAlreadyInFavorites = selectedFavorites.some(item => item.id === currentIndex);
然后修改handlePress:
const handlePress = () => { if (isAlreadyInFavorites) { // 如果已经在收藏里,你可以在这里触发移除收藏的action(如果有写的话) // dispatch(removeFavorite(currentIndex)); setFavorite(false); } else { dispatch( addFavorite({ id: currentIndex, title: getIds[currentIndex].title, liked: 'true', }), ); setFavorite(true); } // 这里的setTimeout可以删掉了,状态应该由实际的收藏情况决定 };
这样一来,不管用户点多少次同一个项,都只会添加一次,也不会出现key重复的问题啦。
备注:内容来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

