javascript - 尽管使用扩展运算符制作状态副本,但 Redux 状态突变
问题描述
为什么在使用扩展运算符制作对象副本时会收到状态突变警报?我正在尝试用 redux 制作购物车。当添加一个元素或减少它的数量时,我调度一个更新状态的动作。在我的减速器中,如果尚未添加产品,我将返回状态数组的新副本和新对象。如果它已被添加,我将使用 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"....}
解决方案
您正在改变当前项目。前/后递增/递减将改变它操作的当前对象引用。
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 } // <-- This mutates the current item.qty
: item
),
};
但是,您可以返回一个递增的值,当前item.qty + 1
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 + 1 }
: item
),
};
我怀疑您的代码按预期运行,因为您确实正确替换了整个购物车数组,并且您变异的项目是您想要更新的项目,但这表明您的减速器可能不是纯函数,即之前的状态应该仍然在reducer计算下一个状态后,在所有方面都等于前一个状态。
推荐阅读
- java - 如何将平面 JSON 转换为分层 java 类?
- ios - 如何在 Swift 中从 SKScene 呈现 UiView
- html - 百分比填充不响应浏览器宽度
- matlab - 更改鼠标单击滚动的滑块跳跃大小
- c# - 是否应该在 Web 应用程序中禁用实体框架延迟加载?
- amazon-web-services - 如何修复漂移的 AWS CloudFormation 堆栈?
- reactjs - 处理来自 GraphQL 查询(带有片段)响应的数据?
- sql-server - 计算带有条件的大型 SQL Server 表中总行数的最快方法是什么
- c# - 如何在一定时间后停止产生攻击者?
- linux - 将“手工”htaccess 移动到 nginx 配置