You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:36:02