尽管使用传播运算符进行状态复制,但仍存在 Redux 状态突变

为什么我在使用传播运算符复制对象时收到状态突变警报?我正在尝试用redux制作一个购物车。当添加元素或减少其数量时,我会调度一个更新 de 状态的操作。在我的化简器中,如果尚未添加产品,我将返回带有新对象的状态数组的新副本。如果已经添加了它,我将使用map(返回一个新数组)和我正在增加的产品的副本进行迭代,并且其属性增加。问题是此属性 在不改变状态的情况下更新此属性的正确方法是什么?qty


还原剂


case types.ADD_TO_CART_SUCCESS:

  const isAdded = state.cart.find(item => item.sku === action.product.sku);

  if (!isAdded) action.product.qty = 1;

  return {

    ...state,

    cart: !isAdded

      ? [action.product, ...state.cart]

      : state.cart.map(item =>

          item.sku === action.product.sku

            ? { ...item, qty: ++item.qty }

            : item

        ),

  };

违规警告


Invariant Violation: A state mutation was detected inside a dispatch, in the path: `user.cart.0.qty`. Take a look at the reducer(s) handling the action {"type":"ADD_TO_CART_SUCCESS"....}



杨__羊羊
浏览 172回答 3
3回答

www说

您正在改变当前项。前/后递减/递减将改变它所操作的当前对象引用。case types.ADD_TO_CART_SUCCESS:&nbsp; const isAdded = state.cart.find(item => item.sku === action.product.sku);&nbsp; if (!isAdded) action.product.qty = 1;&nbsp; return {&nbsp; &nbsp; ...state,&nbsp; &nbsp; cart: !isAdded&nbsp; &nbsp; &nbsp; ? [action.product, ...state.cart]&nbsp; &nbsp; &nbsp; : state.cart.map(item =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.sku === action.product.sku&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? { ...item, qty: ++item.qty } // <-- This mutates the current item.qty&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : item&nbsp; &nbsp; &nbsp; &nbsp; ),&nbsp; };但是,您可以返回递增的值,当前item.qty + 1case types.ADD_TO_CART_SUCCESS:&nbsp; const isAdded = state.cart.find(item => item.sku === action.product.sku);&nbsp; if (!isAdded) action.product.qty = 1;&nbsp; return {&nbsp; &nbsp; ...state,&nbsp; &nbsp; cart: !isAdded&nbsp; &nbsp; &nbsp; ? [action.product, ...state.cart]&nbsp; &nbsp; &nbsp; : state.cart.map(item =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.sku === action.product.sku&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? { ...item, qty: item.qty + 1 }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : item&nbsp; &nbsp; &nbsp; &nbsp; ),&nbsp; };我怀疑您的代码按预期运行,因为您确实正确替换了整个购物车数组,并且您变异的项目是您想要更新的项目,但这表明您的化简器可能不是纯函数,即在化简器计算下一个状态后,先前的状态在所有方面仍应等于先前的状态。

Helenr

看起来您正在使用我们的官方 Redux Toolkit 包,默认情况下,该包将警告意外状态突变。这很好,因为它显然在这种情况下发现了一个突变。但是,更好的是,Redux Toolkit在内部使用Immer来让你在化简器中编写“变异”状态更新!这意味着您的化简器逻辑可以简化为:const cartSlice = createSlice({&nbsp; name: 'cart',&nbsp; initialState,&nbsp; reducers: {&nbsp; &nbsp; addToCartSuccess(state, action) {&nbsp; &nbsp; &nbsp; const item = state.cart.find(item => item.sku === action.payload.product.sku);&nbsp; &nbsp; &nbsp; if (item) {&nbsp; &nbsp; &nbsp; &nbsp; item.qty++;&nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; action.product.qty = 1;&nbsp; &nbsp; &nbsp; &nbsp; state.cart.unshift(action.payload.product);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }})

慕仙森

我做了几次这样的东西,试试这个代码:const addItemToCart = (cartItems, cartItemToAdd) => {&nbsp; const existingCartItem = cartItems.find(&nbsp; &nbsp; (cartItem) => cartItem.id === cartItemToAdd.id&nbsp; );&nbsp; if (existingCartItem) {&nbsp; &nbsp; return cartItems.map((cartItem) =>&nbsp; &nbsp; &nbsp; cartItem.id === cartItemToAdd.id&nbsp; &nbsp; &nbsp; &nbsp; ? { ...cartItem, quantity: cartItem.quantity + 1 }&nbsp; &nbsp; &nbsp; &nbsp; : cartItem&nbsp; &nbsp; );&nbsp; }&nbsp; return [...cartItems, { ...cartItemToAdd, quantity: 1 }];};
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript