React Native收藏列表:如何实现商品单独添加与逐个删除功能?
问题:收藏功能无法追加商品,且无法正确删除单个收藏项
当前点击「添加至收藏」按钮时,新商品会替换原有收藏商品而非追加;同时无法正确删除单个收藏商品。以下是问题代码及修复方案:
原Context代码
const initialState = { products: ProductData, cart: [], FavoritesList: [], }; const reducer = (state = initialState, action) => { switch(action.type) { case 'ADD_PRODUCT_TO_FAVORITE': const product = action.payload; const index = state.FavoritesList.findIndex( (item) => item?.id === product?.id ); if (index !== -1) { return { ...state, products: state.FavoritesList.filter((_, i) => i !== index), }; } else { return { ...state, products: state.FavoritesList.concat(product), }; } case 'DELETE_FAVORITE_PRODUCT': return { ...state, products:state.products.filter((item)=> item?.id === product?.id) }; case 'CLEAR': return { cart: [] } default: throw new Error(`unknow action.${action.type}`) } }
原收藏页面代码
const Faviroute = () => { const { favorites, products } = useCart(); const dispatch = useDispatch(); const Clear = (index) => { dispatch({ type: "DELETE_FAVORITE_PRODUCT", index }); }; return ( <View style={{ flex: 1, }} > {(products.length === 0) ? <View> <Text>Just add the items you would & place your order here.</Text> </View> : <View style={{flex:1,}}> {/*Card Container*/} <ScrollView> <View> {products.map((item, index) => ( <View key={index}> <Image source={item.image} /> <TouchableOpacity onPress={() => Clear(item)}> <Image source={icons.love} /> </TouchableOpacity> </View> ))} </View> </ScrollView> </View> } </View> ) }
修复方案
1. 修正Reducer逻辑
核心问题是错误地操作了products(原始商品列表)而非FavoritesList(收藏列表),同时删除逻辑存在变量未定义、过滤条件错误的问题:
const initialState = { products: ProductData, cart: [], FavoritesList: [], }; const reducer = (state = initialState, action) => { switch(action.type) { case 'ADD_PRODUCT_TO_FAVORITE': const product = action.payload; const existingIndex = state.FavoritesList.findIndex( (item) => item?.id === product?.id ); if (existingIndex !== -1) { // 商品已在收藏列表,移除它(实现点击切换收藏状态) return { ...state, FavoritesList: state.FavoritesList.filter((_, i) => i !== existingIndex), }; } else { // 商品不在收藏列表,追加到列表 return { ...state, FavoritesList: [...state.FavoritesList, product], }; } case 'DELETE_FAVORITE_PRODUCT': const targetId = action.payload; return { ...state, FavoritesList: state.FavoritesList.filter(item => item?.id !== targetId), }; case 'CLEAR': return { ...state, cart: [] } default: throw new Error(`unknown action: ${action.type}`) } }
修复点说明:
ADD_PRODUCT_TO_FAVORITE:改为操作FavoritesList,用扩展运算符替代concat保持语法一致性DELETE_FAVORITE_PRODUCT:从action.payload获取目标商品ID,过滤收藏列表保留非目标项,修复变量未定义问题CLEAR:保留原有state结构,避免覆盖其他状态- 修正拼写错误
unknow→unknown
2. 修正收藏页面组件
组件存在错误引用原始商品列表products而非收藏列表FavoritesList,以及删除函数参数传递错误的问题:
const Faviroute = () => { const { FavoritesList } = useCart(); const dispatch = useDispatch(); const removeFavorite = (productId) => { dispatch({ type: "DELETE_FAVORITE_PRODUCT", payload: productId }); }; return ( <View style={{ flex: 1 }}> {FavoritesList.length === 0 ? ( <View> <Text>请添加您喜欢的商品到收藏夹</Text> </View> ) : ( <View style={{ flex: 1 }}> <ScrollView> <View> {FavoritesList.map((item) => ( <View key={item.id}> <Image source={item.image} /> <TouchableOpacity onPress={() => removeFavorite(item.id)}> <Image source={icons.love} /> </TouchableOpacity> </View> ))} </View> </ScrollView> </View> )} </View> ) }
修复点说明:
- 从context中获取
FavoritesList作为收藏数据源 - 删除函数改为传递商品ID,避免传递整个对象
- 用商品ID作为列表项的key,比index更稳定,提升渲染性能
- 修正空状态提示文本的语法错误
- 调整代码格式,提升可读性
内容的提问来源于stack exchange,提问作者Omar Bakoban
相关产品推荐
相关产品推荐

