Redux从购物车中删除一个项目

Redux从购物车中删除一个项目,redux,react-redux,Redux,React Redux,我已经在react native中构建了一个应用程序,我正在使用react redux将数据存储在购物车中 目前,当我添加一个产品,让我们说苹果到我的购物车。我的购物车将包含1个苹果,如果我添加相同的产品到我的购物车,我将有2个苹果 问题 但是,如果我试图移除1个苹果,我的购物车将移除购物车中的所有苹果 问题 如何在-1之前删除购物车中的项目 cartitems.js case 'REMOVE_FROM_CART': return state.filter(cartI

我已经在
react native
中构建了一个应用程序,我正在使用
react redux
将数据存储在购物车中

目前,当我添加一个产品,让我们说苹果到我的购物车。我的购物车将包含1个苹果,如果我添加相同的产品到我的购物车,我将有2个苹果


问题

但是,如果我试图移除1个苹果,我的购物车将移除购物车中的所有苹果


问题

如何在-1之前删除购物车中的项目

cartitems.js

case 'REMOVE_FROM_CART':
            return state.filter(cartItem=>cartItem.id !== 
                action.payload.id )
<Products products={appels} onPress={this.props.addItemToCart}/>
CartProducts.js组件

<View key={products.index} style={styles.appels}>
      <View style={styles.iconContainer}> 
           <Icon name={products.item.icon} color="#DD016B" size={25} />
      </View>
      <View style={styles.text}>
           <Text style={styles.name}>
                {products.item.name}
           </Text>

           <Text style={styles.price}>
                € {products.item.price}
           </Text>
    </View>
    <View style={styles.buttonContainer}>
          <TouchableOpacity onPress={() => this.props.onPress(products.item)} > 
              <Icon style={styles.button} name="ios-remove" color="white" size={25} />
           </TouchableOpacity>
        </View>
     </View>
const mapDispatchToProps = (dispatch) =>{
    return{
        removeItem:(product) => dispatch ({
            type:'REMOVE_FROM_CART' , payload: product
        })  
    }
}

嗯,您可能需要在操作负载中传递数量或递增/递减标志

您的操作创建者可以接受递增/递减参数

const updateItem = dispatch=>(increment=true)=>{
  dispatch({type:'UPDATE_IN_CART' , payload: product, increment})
}
现在在你的减速机里

case 'UPDATE_IN_CART':{
   const {increment, payload}= action;  //ES6 destructing
   const updatedCart = state.map((cartItem)=>{
      if(cartItem.id !== payload.id )){
          cartItem.quantity = increment?cartItem.quantity+1:cartItem.quantity-1 //will handle increment/decrement; 
      }
      return cartItem;
   })
   return updatedCart;
}
当做

返回状态.filter(cartItem=>cartItem.id!==action.payload.id)

你基本上是说,除了这件物品之外,把所有东西都退回

那不是你想要的。你想给:

  • 有效负载中要移除的数量
  • 产品的id
下面是你的行动:

dispatch({type:'REMOVE_FROM_CART' , payload: {product, qty} })
然后,您必须找到您的物品并更新其数量:

case 'REMOVE_FROM_CART':

      const updatedProductList = state.productList.map( (product) => {
          if(product.id === payload.product.id){ // this is the item we care about
            return {
              ...product, // this will avoid a state mutation
              qty : product.qty - payload.qty // update the qty
            }
          }else { // just return the element as it is
            return cartItem
          }
        })

    return updatedCartItemList;
break;
default :
 return state

我相信,当添加同一产品的多个副本时,您会在该州保留同一产品的副本。因此,您应该只筛选第一个匹配项,而不是所有匹配项:

case 'REMOVE_FROM_CART': {
  const index = state.findIndex(item => item.id === action.payload.id);
  return state.filter((_, i) => i !== index);
}
这将使它在保持当前设计的同时工作

但是,如果用户从列表底部删除了重复的产品,则UI可能不直观,因为列表中产品的第一个副本将从UI中删除,因此,您可能需要调整
removietem
操作负载,以包含要删除的产品的索引,而不是产品对象

更好的方法可能是使用
qty
变量来指示多个副本,这将减少状态大小并使在购物车屏幕上显示数量列更容易(而不是显示重复的产品):


如果使用此新设计,您的
CartScreen.js
也需要相应修改。

这会直接变异。我认为这会导致状态变异。我认为,您必须使用扩展运算符返回它,过滤器和映射不是变异函数,它们作用于数组的副本。数组不会变异,但是它是元素威尔-它仍然是一个突变。谢谢你的回应。添加
dispatch({type:'REMOVE_FROM_CART',payload:{product,qty}}})时
表示
qty
未定义?如果我在添加产品时需要添加
qty
,会发生这种情况吗?我尝试将其添加到
add\u item
中,但get也找不到变量
qty
我在
CartScreen.js
中声明了一个变量const qty=null,现在得到一个新的错误
未定义的不是对象(评估状态.productList.map)
在cartItems中。我现在想弄清楚什么是未定义的谢谢你的回答,有没有地方可以找到如何修改的地方?例如,这改变了我添加到购物车和删除购物车的方式。你能解释一下这个函数是如何工作的吗?如果你想保留当前的函数/UI,你可以使用我的建议,即按索引过滤。如果要更改为存储数量而不是重复数量,则需要显示“数量”列并允许用户修改数量,并且减速机会将匹配项目的
数量设置为操作负载的指定数量。我已在我的矿井中成功使用了您的代码,但如何更新我的购物车屏幕中的实时数量?我需要重新加载页面以查看结果?如果呈现的数量值直接来自连接的redux存储,则当存储更新时,屏幕应自动使用更新的值重新呈现。我将其呈现为
{products.item.qty}
将其连接到
存储
,但它看起来是静态的。
case 'ADD_ITEM_TO_CART':
  if (state.some(item => item.id === action.payload.id)) {
    // increase qty if item already exists in cart
    return state.map(item => (item.id === action.payload.id ? { ...item, qty: item.qty + 1 } : item));
  }
  return [...state, { ...action.payload, qty: 1 }]; // else add the new item to cart

case 'REMOVE_FROM_CART':
  return state
    .map(item => (item.id === action.payload.id ? { ...item, qty: item.qty - 1 } : item))
    .filter(item => item.qty > 0);