首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Redux Thunk,Modifying state: Unhandled rejection: Error:[ Immer ] Immer仅支持设置数组索引和'length‘属性]

Redux Thunk是一个Redux中间件,用于处理异步操作。它允许在Redux的action创建函数中返回一个函数而不是一个普通的action对象。这个返回的函数可以在异步操作完成后再dispatch相应的action,从而实现异步流程的控制。

在Redux中,当使用Redux Thunk中间件时,action创建函数可以返回一个函数。这个函数可以接收两个参数:dispatch和getState。通过dispatch函数,我们可以dispatch其他的action,而getState函数可以获取当前Redux store的状态。

对于Modifying state: Unhandled rejection: Error:[ Immer ] Immer仅支持设置数组索引和'length‘属性的错误,这是由Immer库引起的。Immer是一个用于简化状态修改的库,它通过创建原始状态的可变草稿副本,并追踪对该草稿的所有修改来实现这一目的。然而,Immer只支持修改数组索引和'length'属性,而不支持直接修改数组或对象的其他属性。

解决这个错误的方法是使用Immer提供的produce函数来修改状态。produce函数接受一个原始的状态和一个函数作为参数。在函数中,我们可以直接修改状态,Immer会在内部追踪这些修改并返回一个新的状态。最后,我们将新的状态返回给Redux的reducer处理。

以下是一个示例代码,展示了如何在Redux中使用Redux Thunk处理异步操作,以及如何在处理状态修改时使用Immer解决上述错误:

代码语言:txt
复制
import { createSlice } from '@reduxjs/toolkit';
import { produce } from 'immer';

// 使用createSlice创建Redux slice
const counterSlice = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
    increment: (state) => state + 1,
    decrement: (state) => state - 1,
  },
});

// 创建异步action创建函数
export const incrementAsync = () => {
  return (dispatch, getState) => {
    setTimeout(() => {
      // 使用getState获取当前状态
      const currentState = getState();

      // 使用produce函数修改状态
      const nextState = produce(currentState, (draftState) => {
        draftState.counter += 1;
      });

      // dispatch修改后的action
      dispatch(counterSlice.actions.increment(nextState.counter));
    }, 1000);
  };
};

export default counterSlice.reducer;

在上面的示例中,我们定义了一个名为counter的Redux slice,并创建了两个同步的action:increment和decrement。然后,我们定义了一个名为incrementAsync的异步action创建函数,它使用setTimeout模拟异步操作。在函数中,我们使用getState获取当前状态,并使用produce函数修改状态。最后,我们dispatch修改后的increment action。

关于Redux Thunk和Immer的更多信息,可以参考以下链接:

  • Redux Thunk官方文档:Redux Thunk
  • Immer官方文档:Immer
  • 腾讯云相关产品:由于不涉及云计算品牌商信息,请自行搜索腾讯云相关产品。
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • Immer使用指南

    (如果没有在 draft 中对 state 对象做修改,那么返回值原对象是一样的,绝对相等) 此外,它还使得克隆成本相对较低: 原对象中,未更改的属性(树)部分不做复制,在内存中与原旧版本的属性共享属性...当使用Immer时,只需要对 draft对象进行更改,draft对象会先记录用户的修改, 然后创建有变更的必要的属性副本,不会影响原始对象。...对JSON补丁的一流支持 7. 体积小,gzipped 压缩后3 kb ---- 二、Immer的使用场景 应用的场景有: 1. 用于 React 的 state 的变更。...React 的 state 本身是不可修改的,当你需要修改它的某个属性然后保存为新的状态的时候, 使用 immer 可以很方便的获得一个新的 state。 2....如果在 draft 中没有值的变更或者变更值原对象一致,则返回原对象。 当给 draft 设置赋值产生变更之后,setter 就会对原对象的 copy 对象进行赋值,之后再返回 copy 对象。

    1.7K20

    【React】211- 2019 React Redux 完全指南

    你的函数调用时会接收两个参数:上一次迭代的结果,当前数组元素。它结合当前元素之前的 “total” 结果然后返回新的 total 值。...Redux 基本上是数组 reduce 的豪华版。...只要它是个带有 type 属性的对象就可以了。 为了保证事务的合理性可维护性,我们 Redux 用户通常给 actions 的 type 属性赋简单字符串,并且通常是大写的,来表明它们是常量。...我整理了一个如何在 Redux 里做 Immutable 更新完全指南,包含更新 state 中对象和数组的七个通用模式。 安装 Immer 在 reducers 里面使用也是一种很好的方式。...好吧,connect 为你提供支持:除了传递(mapped)state,它还从 store 传递了 dispatch 函数!

    4.2K20

    redux你用对了吗?

    redux 的三大原则 redux 的开发使用必须要遵循三大原则,即: 单一数据源:整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个...比如,state newState 是两个不同的对象,这两个对象里面的 content 属性在我们的场景中是不需要修改的,因此 content 属性可以指向同一个对象,但是因为 title 被一个新的对象覆盖了...== Object.keys(state).length return hasChanged ?...immer 上面我们已经分析了 redux 里面的 reducer 为什么要返回一个全新的 state,但是,如果按照上面 reducer 的写法,要修改的 state 树层级深了之后,修改起来无疑是非常麻烦的...从源码角度分析了需要返回全新state的原因,最后引入了immer库,引入了 immutable 概念,redux 配合 immer 可以方便我们便捷高效的用好 redux

    58230

    使用Immer解决React对象深度更新的痛点

    React 不允许直接更改state ,而应该使用 setState setState 会合并更改(merge update),所以不需要手写完整的state,但是合并仅限于对象属性的第一级 setState...那么怎么样避免深拷贝所有属性,而只针对目标属性(子节点)?...提供的produce方法,可以直接像深拷贝那样,在新对象上做修改 更重要的是,在 immer 的背后做了性能优化,而不是简单的全部深度拷贝,所以不用担心性能问题 Immer 的优点 Immer有着许多便捷性能上的优势...: 遵循不可变数据范式,同时使用普通的JavaScript对象、数组、集合映射,上手即用 开箱即用的结构共享 开箱即用对象冻结 更新轻而易举 冗余代码更少 对JSON补丁的一流支持 仅有3KB Immer...上作修改 immer 接收修改后的draft,immer 基于传入的 state 照着draft 的修改 返回一个新的 state Immer Hook 如果你觉得每次调用setState的时候都需要配合使用一次

    83741

    放弃Redux吧,转投Zustand吧

    它是由 Max Stoiber 创建的,并且得到了社区的广泛支持使用。...中间件支持 Zustand 支持大量的中间件,如 ImmerRedux 中间件等,这使得开发者可以根据需要轻松地扩展 Zustand 的功能。...(error) { set(state => ({ error, loading: false })) } }, })) 通过这些基本步骤高级特性,可以开始在 React 应用程序中使用...这意味着即使在页面刷新或关闭后,状态也能够被保留恢复。这个功能对于那些需要持久保存用户操作的场景非常有用,比如表单数据、用户偏好设置等。...whitelist: 一个数组,指定哪些状态应该被持久化。只有包含在数组中的状态才会被保存。 blacklist: 一个数组,指定哪些状态不应该被持久化。这是一个取反的 whitelist。

    44010

    前端基建规范参考

    状态管理器优化统一 # 3.1 优化状态管理 用react的context封装了一个简单的状态管理器,有完整的类型提升,支持在组件内外部使用,也发布到?...类型自动推断,在实例化的时候传入类型,在设置获取值的时候都会自动类型推断。 可以统一管理,把本地存储都放在一个文件里面,避免后期本地存储混乱不好维护问题。...引入 immer 来优化性能简化写法 ?...Immer 是 mobx 的作者写的一个 immutable 库,核心实现是利用 ES6 的 Proxy(不支持Proxy的环境会自动使用Object.defineProperty来实现),几乎以最小的成本实现了...以数组为例,修改购物车某个商品的数量: import produce from 'immer' const [ list, setList ] = useState([{ price: 100, num

    23730

    简单通俗的理解Vue3.0中的Proxy

    )我们需要安装额外的包来进行支持,比如 core-js/stable regenerator-runtime/runtime (PS:babel 7.x 之后@babel/polyfill已不推荐使用...检测不到对象属性的添加删除:当你在对象上新加了一个属性newProperty,当前新加的这个属性并没有加入vue检测数据更新的机制(因为是在初始化之后添加的)。vue....$set是能让vue知道你添加了属性, 它会给你做处理,$set内部也是通过调用Object.defineProperty()去处理的 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应...'; console.log(p.newPropKey); 可以看到下面输出 // 修改原对象的age属性设置了age 新的age=20 你访问了age 20 // 设置新的属性设置了newPropKey...immer 的做法就是维护一份 state 在内部,劫持所有操作,内部来判断是否有变化从而最终决定如何返回,具体内容可以看一下immer.js 简介及源码简析 这篇文章。

    1.5K30

    潜心优化,limu终达不可变数据性能之巅

    倍以上(3.12之前数据为4倍左右) 代码结构简洁 由于只考虑支持Proxy,代码设计没有历史包袱,可以专注于数据读写、代理生成、冻结实现等不可变数据的核心场景,利于后期升级扩展更多面向现代浏览器标准的特性...pureObj, Object.prototype); Object.setPrototypeOf(rawObj, pureObj); return rawObj; } 这样达成了使用symbol藏匿私有属性使用重建原型链达到提升私有属性到原型链上且不污染原型链的效果...,我们的的是测试数据包含一个20+key的字典, key对应的数据深度为 26层 同时还会生成一个长度10000的数组 测试角色准备 测试角色除了immer,limu,mutative,structura...这四个库,还新增了pstrnative pstr使用JSON.parseJSON.stringify来模拟immer的produce // code of pstr exports.createDraft...,时间相对上一组均提升了2到3倍,structura immer 在此场景表现依然不如硬克隆pstr,limu表现最好,mutative次之。

    21810

    共享可变状态中出现的问题以及如何避免

    浅拷贝与深拷贝 对于数据,有两个可复制的“深度”: 浅拷贝复制对象和数组的顶层条目。原始值副本中的输入值仍然相同。 深拷贝还会复制条目值的条目。也就是说,它会完整遍历树,并复制所有节点。...例如数组实例自己的属性 .length 不可枚举,也不能复制: 1const arr = ['a', 'b']; 2assert.equal(arr.length, 2); 3assert.equal(...示例:以破坏性非破坏性的方式更新数组 以下是破坏性地设置数组元素的方式: 1const original = ['a', 'b', 'c', 'd', 'e']; 2original[2] = 'x'...其中流行的两种是: Immutable.js 提供了不变(版本)的数据结构,例如 List,Map,Set Stack。 Immer支持不可变性非破坏性更新,但适用于普通对象和数组。...Immer 在其存储库中,Immer 库 的描述为: 通过更改当前状态来创建下一个不可变状态。 Immer 有助于非破坏性地更新(可能嵌套)普通对象和数组。也就是说,不涉及特殊的数据结构。

    1.6K40

    Redux 做状态管理,真的很简单🦆!

    想要记录每一个状态,如果直接修改 state 中的引用类型属性,势必会导致 state 的变化不可追溯预测。...Redux 期望所有状态更新都是使用不可变的方式,因此,每一次的 state 变更,不会修改原对象,而是修改前一个状态(state)的克隆对象,以此来保证不可变性正确性,同时记录每一次变化的 state...借助 @redux/toolkit,不再需要刻意关心如何组织编写 Reducer、Action creator、Action Type 等内容,同时,默认就融合支持 异步 Thunks 再结合 React...) => { state.value += 1; // 这里默认通过了 immer 处理,不会修改原 state }, decrement: (state) => {...React 项目选择 Redux 作为全局的状态管理还是非常推荐的,结合 React 16.x 的 Hooks 状态更新,非常方便,也符合函数组件的编码风格,再瞅瞅 React 的 useContext

    3.4K40
    领券