React redux toolkit: Uncaught Error:[Immer] An immer producer returned a new...
React在写一个购物车的redux toolkit时遇到了问题。核心代码如下:
import { createSlice } from "@reduxjs/toolkit";
const cartSlice = createSlice({
name: 'cart',
initialState: {
cartItems: [],
cartItemCount: 0
},
reducers: {
addProduct(state, action) {
const { imageUrl, name, price } = action.payload
let newCartItems = [...state.cartItems]
let flag = newCartItems.some((item, index, arr) => {
if(item.name == name) {
arr[index].quantity += 1
return true
}
})
if(!flag) {
newCartItems = [
...state.cartItems,
{ imageUrl, name, price, quantity: 1 }
]
}
const cartItemCount = newCartItems.reduce(
(prevTotal, currItem) => prevTotal + currItem.quantity, 0
)
return { cartItems: newCartItems, cartItemCount }
}
}
})
export const { addProduct, deleteProduct, incQuantity, decQuantity } = cartSlice.actions
export default cartSlice.reducer
核心逻辑是,调用addProduct来修改redux所管理的cartItems和cartItemCount,当向购物车中添加一个新的物品时,代码正常运行;但当反复添加一个物品时,代码报出如下错误:
搜下资料发现是因为redux使用immer,不允许在reducer中修改state值后还return,二者只能取其一。
因此,当添加一个新物品时,由于没有修改cartItems,因此可以有返回值,不报错。
但当添加一个重复的物品时,即使在最开始使用了let newCartItems = [...state.cartItems]
来创建一个新的对象,但由于state.cartItems
数组中保存的不是基本数据类型,而是一个对象,因此newCartItems
保存的是state.cartItems
中各个对象的引用,即
newCartItems == state.cartItems // false
newCartItems[0] == state.cartItems[0] // true
由此可得,添加一个新物品时,由于既修改了state,又return了新值,因此报出immer错误。
修改后的代码如下:
addProduct(state, action) {
const { imageUrl, name, price } = action.payload
let flag = state.cartItems.some((item, index, arr) => {
if(item.name == name) {
arr[index].quantity += 1
state.cartItemCount += 1
return true
}
})
if(!flag) {
state.cartItems.push({ imageUrl, name, price, quantity: 1 })
state.cartItemCount += 1
}
}
这里只是对state做了修改,而没有return新值,因此代码正常运行。
React redux toolkit: Uncaught Error:[Immer] An immer producer returned a new...的更多相关文章
- webpack+react+redux+es6开发模式---续
一.前言 之前介绍了webpack+react+redux+es6开发模式 ,这个项目对于一个独立的功能节点来说是没有问题的.假如伴随着源源不断的需求,前段项目会涌现出更多的功能节点,需要独立部署运行 ...
- webpack+react+redux+es6开发模式
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- react+redux教程(一)connect、applyMiddleware、thunk、webpackHotMiddleware
今天,我们通过解读官方示例代码(counter)的方式来学习react+redux. 例子 这个例子是官方的例子,计数器程序.前两个按钮是加减,第三个是如果当前数字是奇数则加一,第四个按钮是异步加一( ...
- webpack+react+redux+es6
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- React Redux Sever Rendering实战
# React Redux Sever Rendering(Isomorphic JavaScript) ![React Redux Sever Rendering(Isomorphic)入门](ht ...
- react+redux+generation-modation脚手架添加一个todolist
当我遇到问题: 要沉着冷静. 要管理好时间. 别被bug或error搞的不高兴,要高兴,又有煅炼思维的机会了. 要思考这是为什么? 要搞清楚问题的本质. 要探究问题,探究数据的流动. TodoList ...
- 详解react/redux的服务端渲染:页面性能与SEO
亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染) react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...
- 实例讲解基于 React+Redux 的前端开发流程
原文地址:https://segmentfault.com/a/1190000005356568 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 s ...
- 【redux】详解react/redux的服务端渲染:页面性能与SEO
亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染) react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...
- 我的第一个 react redux demo
最近学习react redux,先前看过了几本书和一些博客之类的,感觉还不错,比如<深入浅出react和redux>,<React全栈++Redux+Flux+webpack+Bab ...
随机推荐
- C# 锁汇总
一.前言 本文章汇总c#中常见的锁,基本都列出了该锁在微软官网的文章,一些不常用的锁也可以参考微软文章左侧的列表,方便温习回顾. 二.锁的分类 2.1.用户模式锁 1.volatile 关键字 vol ...
- Hihocoder 1067
最近公共祖先二 离线算法 /**/ #include <cstdio> #include <cstring> #include <cmath> #include & ...
- EL_获取域中存储的值_ List 集合&Map集合值和EL _ empty 运算符&隐式对象 pageContext
3.获取对線. List 集合. Map 集合的值 1.对線:${域名称,键名.属性名}本质上会去调用对線的 getter 方法 2. List 集合:${域名称.键名[索引]} List list ...
- Linux调用python文件的同时传参
创建python文件内容如下: 计算两个数相加并打印,需要传递两个参数 vi sum.py import sys def calc(a,b): c=a+b return c a1=int(float( ...
- 转载:VMware Esxi开通SSH功能
转载:https://www.cnblogs.com/dsl146/p/13739953.html ESXi 5.5是直接安装在物理主机上的一个虚拟机系统,本质上是一个Linux系统.平时可以通过VM ...
- Java8中Stream()流的用法总结
简单的集合遍历 foreach遍历 import java.util.ArrayList; import java.util.List; /** * @author rx * @date 2022/6 ...
- 阿里云CentOS7 下部属nginx+uwsgi+python3+django
安装依赖包 yum -y groupinstall "Development tools" yum install openssl-devel bzip2-devel expat- ...
- el-scrollbar element-ui的滚动条组件(官方文档没有写出来)
<el-scrollbar></el-scrollbar> //去掉横向滚动条 /deep/.el-scrollbar__wrap { overflow-x: hidden; ...
- bind、call、apply区别
bind.call.apply都是用来改变函数内部this指向的方法,使用上仅有细微差别 一.代码 function person(p1, p2, p3) { console.log('this: ' ...
- SDK测试标准
测试分类 具体测试项 测试内容 测试方法 文档测试 接口清单 接口清单是否完整,正确,包含提供给开发者的协议所有字段的定义和解释 人工检查 更新说明 要说明新增,删除的接口定义 Demo示例 显示如何 ...