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

为什么我的immer reducer没有返回新值,即使草稿已经改变了?

问题描述:

为什么我的immer reducer没有返回新值,即使草稿已经改变了?

答案:

这个问题的出现可能是由于immer的使用不当造成的。immer是一个用于处理不可变数据的JavaScript库,它可以帮助我们更方便地修改数据而不改变原始对象。

在使用immer时,我们需要明确一些规则:

  1. immer只能用于处理纯函数式的reducer函数,它会确保我们返回一个新的状态。
  2. immer会对传入的reducer函数进行封装,在其中提供一个代理对象,我们只需要在这个代理对象上进行修改即可。
  3. immer会自动跟踪我们对代理对象的修改,并将这些修改应用到新的状态上。

如果我们的immer reducer没有返回新值,即使草稿已经改变了,可能是由于以下原因:

  1. 忘记使用immer.produce函数:immer.produce是immer提供的一个高阶函数,用于创建一个新的reducer函数。我们需要在创建reducer函数时使用immer.produce,才能确保返回一个新的状态。
  2. 对草稿进行了直接修改:由于immer只能处理纯函数式的reducer函数,因此我们不能直接修改草稿对象。我们应该在代理对象上进行修改,immer会自动将这些修改应用到新的状态上。
  3. 草稿的属性没有正确被访问:如果我们对草稿的属性进行修改,但没有正确地访问这些属性,那么immer可能无法跟踪到我们的修改。我们需要确保对草稿属性的访问是正确的。

为了解决这个问题,我们可以按照以下步骤进行操作:

  1. 确保在创建reducer函数时使用immer.produce,例如:
代码语言:txt
复制
const reducer = immer.produce((draft, action) => {
  // 在这里对代理对象进行修改
});
  1. 确保对草稿的属性进行正确的访问和修改,例如:
代码语言:txt
复制
const reducer = immer.produce((draft, action) => {
  draft.property = action.payload; // 正确的属性访问和修改方式
});
  1. 检查是否有其他逻辑错误导致immer无法正常工作,例如条件判断、循环等。

希望这些解释和建议能帮助你解决问题。如果有更多关于immer和reducer的问题,请随时提问。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为什么说 90% 的情况下,immer 能完胜 immutable?

我们测试一下: 用上图的方式 setState,整个 state 变了,但是 key 对应的值没有变。...时,会对比 state 本身变没变,变了就会重新渲染 为什么 function 组件里只对比了 state 没有对比每个 key 的值也很容易理解,因为本来每个 state就是用 useState 单独声明的了...但这样又有了一个新的问题: 如果 state 的内容很多呢? 而你只想修改其中的一部分,要把整个对象复制一次: 是不是很麻烦? 能不能我修改了对象的值,立马给我返回一个新的对象呢?...这样返回的是 immutable 的数据结构,并且对 b 做了修改: 你和之前的 a 属性的值对比下,发现也不一样了: 这就是它的作用,修改值以后返回新的 immutable 数据结构。...immer 只有一个 produce api,传入原对象和修改函数,返回的就是新对象,使用新对象就是普通 JS 对象的用法。

45220
  • Immer使用指南

    (如果没有在 draft 中对 state 对象做修改,那么返回值和原对象是一样的,绝对相等) 此外,它还使得克隆成本相对较低: 原对象中,未更改的属性(树)部分不做复制,在内存中与原旧版本的属性共享属性...当你写完之后,助手就会拿起你的草稿,根据草稿内容为你写出真正不能再被修改的、最后版本的书信(即下一个状态)。 Immer 的优势: 1....显然 produce 返回的 nextState 对象和原来的 baseState不一样了。 这是为什么呢?...当访问 draft 时,其定义的 getter 会返回一个 Proxy 代理对象。 如果在 draft 中没有值的变更或者变更值和原对象一致,则返回原对象。...很显然,经过 immer 处理之后的 nextState 修改属性值的时候报错了。 而且,原对象 baseState 修改属性值的时候同样会报错。 immer 改变了原对象!!!

    1.8K20

    使用React hooks处理复杂表单状态数据

    自从React hooks发布以来已经有一段时间了,我很喜欢这个特性。这个hooks把我勾上了! Hooks允许我们创建更小,可组合,可重用,更易管理的React组件。...这样看起来,reducer简洁干净多了。 但是,现在reducer更新参数中如果有回调函数,则不能基于当前状态计算新状态,因为当前state没有传递给回调函数作为参数。...因此,您可以使用包含要更新的状态片段的新对象调用updateState,并将其与旧状态合并并返回新状态。...immer中的produce函数将对象作为其第一个参数进行处理,在我们的例子中是当前状态,它的第二个参数是一个函数,它接收对象的草稿副本以进行mutate,无论你在这个函数内修改了什么草稿状态,是在副本上完成的...然后,它会自动返回包含更新数据的新对象。 这就是我们的增强版reducer。 安装一下依赖,就可以跑起来了。 ?

    3.4K20

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

    React的心智负担 为什么要这样写?...,以及一个修改传入状态的函数,在修改状态的函数中,所有标准的JavaScriptAPI都可以用于draft(草稿)对象,然后返回一个新的状态,但是原始的状态不会受到影响。...,我们通过Immer提供的produce方法,可以直接像深拷贝那样,在新对象上做修改 更重要的是,在 immer 的背后做了性能优化,而不是简单的全部深度拷贝,所以不用担心性能问题 Immer 的优点...(草稿)给我们 我们在 draft 上作修改 immer 接收修改后的draft,immer 基于传入的 state 照着draft 的修改 返回一个新的 state Immer Hook 如果你觉得每次调用...Immer的使用方法,希望对你有用,当然,如果可以的话不妨点个赞再走呢,这对我很重要。

    1K41

    redux你用对了吗?

    add 的返回值永远只依赖他的入参 a 和 b,不管外部变量 x 的值如何变化,也不会影响到函数 add 的返回值。...为什么reducer需要返回一个全新的state 上面我们介绍了什么是纯函数,redux 里面规定 reducer 必须是一个纯函数,并且每个纯函数需要返回一个全新的state,那么这里大家肯定就有一个疑问...,为什么 reducer 必须要返回一个全新的 state,直接修改完了 state 再返回不行吗?...immer 上面我们已经分析了 redux 里面的 reducer 为什么要返回一个全新的 state,但是,如果按照上面 reducer 的写法,要修改的 state 树层级深了之后,修改起来无疑是非常麻烦的...,什么是纯函数,以及为什么 reducer 需要返回一个全新的 state ?

    59030

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

    increment 函数会更新 state 的 count 值。 因为 state 改变了,React 会重新渲染 Counter 组件(以及它的子元素),这样就会显示新计数值。...我们必须提供一个返回 state 的函数。这个函数被称为 reducer(我们马上就知道为什么了)。...你的函数调用时会接收两个参数:上一次迭代的结果,和当前数组元素。它结合当前元素和之前的 “total” 结果然后返回新的 total 值。...给 Reducer 一个初始状态 记住 reducer 的职责是接收当前 state 和一个 action 然后返回新的 state。 它还有另一个职责:在首次调用的时候应该返回初始 state。...但是我向你展示这种困难方式是因为很多代码仍然采用这种方式,你一定会看到没有用 Immer 写的 reducers 全部规则 必须返回一个 state,不要改变 state,不要 connect 每一个组件

    4.3K20

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

    性能优异 由于提前做了浅克隆操作,且只克隆读取过的路径并改变父子节点相互之间的路径指向,在结束草稿时只需判断modified变量真假来瞬间完成新的副本生成动作,在数据大读取少的场景性能超过immer20...优化过程 在3.12之前,limu虽然性能已超过immer数倍,但离structura、mutative这些新起的不可变数据操作库还有不少差距,故只能把调试友好、比immer快几倍来作为宣传点,如需追求极致的速度还是默认推荐了...最终想到了es6的新数据结构Map,在createDraft时为每一个草稿生成一个metaMap,用于放置数据对应的meta即可,伪代码如下: function getProxy(metaMap, dataNode...性能测试 我们已经性能测试相关代码放置到benchmark,你只需要执行以下步骤即可体验到最新版本的性能测试表现。...api设计,如没有用到immer的applyPatches相关api,可实现无感平替。

    24310

    每周学点大数据 | No.38平均数计算

    我希望借助这个例子,仔细讲解一下关于combiner 的问题。 小可:从前面的例子可以看出,其实 combiner 和 Reducer 挺像的,它们做的都是合并工作。 Mr. 王:没错。...至于 Reducer,它是根据字符串进行匹配的,将具有相同键值的字符串以及对应的整数值收集到一起,然后剩下的部分就是对这些值求平均数, sum 累计所有的整数 r, cnt对其出现的 r 的数量进行计数...,最后返回它。...小可恍然大悟,说:哦,这个版本的确有问题, combiner 不仅进行了优化,而且还改变了输入输出数据类型,如果在这里去掉 combiner 的话,那么 Mapper 函数的输出数据类型与Reducer...王:想想看,还可以怎么改? 小可:嗯,这次即使把 combiner 彻底去掉,也不会影响整个程序的运行结果,只是在Mapper 上面稍作修改,效果还是很好的。 Mr.

    1.1K80

    Redux 源码解析系列(一) -- Redux的实现思想

    但是这里存在一个风险就是,谁都可以修改appState的值,换句话说,有一天当appState变了你都不知道是谁改的,所以我们需要有一个管理员来帮我们管理我们的状态,这时候引入了dispatch函数,来专门负责修改数据...到这一步,一个APP就已经可以无压力的跑起来啦,最后一步,当然是关注性能,我们这个app 还是有严重性能问题的,因为每一次的dispatch 一次action,不管数据有没有变化,组件都会被重新渲染,这当然是不必要的...3、为什么reducer是纯函数 所以就需要对reducer产生的前后appState进行一个对比,这就要求reducer必须是一个纯函数,返回的是一个新的object,不能直接更改reducer的参数...} return {getState, dispatch, subscribe} } OK,到这一步,我们的redux就基本完成啦~ 接着改装下我们的reducer,让它有一个初始值,这样我们的...返回的是一个新的object,那在外层,我们就可以对比nextProps跟t his.props 来决定是否渲染 state = reducer(state, action) listeners.forEach

    58910

    Redux 源码解析系列(一) -- Redux的实现思想

    但是这里存在一个风险就是,谁都可以修改appState的值,换句话说,有一天当appState变了你都不知道是谁改的,所以我们需要有一个管理员来帮我们管理我们的状态,这时候引入了dispatch函数,来专门修改负责数据的修改...到这一步,一个APP就已经可以无压力的跑起来啦,最后一步,当然是关注性能,我们这个app 还是有严重性能问题的,因为每一次的dispatch 所有的子组件都会被重新渲染,这当然是不必要的。...所以就需要对reducer产生的前后appState进行一个对比,这就要求reducer必须是一个纯函数,返回的是一个新的object,不能直接更改reducer的参数,这样才能够对比可以通过对比前后的...} return {getState, dispatch, subscribe} } OK,到这一步,我们的redux就基本完成啦~ 接着改装下我们的reducer,让它有一个初始值,这样我们的...返回的是一个新的object,那在外层,我们就可以对比nextProps跟t his.props 来决定是否渲染 state = reducer(state, action) listeners.forEach

    73150

    成为一名高级 React 需要具备哪些习惯,他们都习以为常

    我假设你已经知道React的基础知识,因此不会涉及“不要改变道具或状态”这样的陷阱。 坏习惯 本节中的每个标题都是你应该避免的坏习惯! 我将使用一个典型的待办事项列表应用程序示例来说明我的一些观点。...我们需要跟踪待办事项列表上的项目,以及哪些项目已经被选中。...当状态更新很简单时,useState是非常好的。例如,可以用 usestate跟踪复选框是否被选中,或者跟踪文本输入的值。 话虽如此,当状态更新变得稍微复杂时,您应该使用一个reducer。...我发现中级React开发人员通常不编写测试,即使测试需要5分钟的时间来编写,并且具有中等或高的影响!我将这些情况称为测试的“低垂果实”。试试低垂的果实!!...最好的前端开发者也是可用性和网页设计方面的专家,即使这并没有反映在他们的工作头衔上。 可用性只是指应用程序使用起来有多容易。例如,添加一个新的待办事项到列表中有多容易?

    4.7K40

    Redux Toolkit

    它最初的创建是为了帮助解决关于 Redux 的三个常见问题: “配置 Redux 存储太复杂了” “我必须添加很多包才能让 Redux 做任何有用的事情” “Redux 需要太多样板代码” 我们无法解决所有用例...安装 使用 React 和 Redux 启动新应用程序的推荐方法是使用官方 Redux+JS 模板或Redux+TS 模板来创建 React App,它利用了Redux Toolkit和 React Redux...此外,它自动使用该immer库让您使用普通的可变代码编写更简单的不可变更新,例如state.todos[3].completed = true. createAction():为给定的动作类型字符串生成动作创建函数...函数的对象、切片名称和初始状态值,并自动生成切片reducer,并带有相应的动作创建者和动作类型。...createAsyncThunk: 接受一个动作类型字符串和一个返回承诺的函数,并生成一个pending/fulfilled/rejected基于该承诺分派动作类型的 thunk import { createAsyncThunk

    13010

    完全理解 redux(从零实现一个 redux)

    /*来订阅一下,当 count 改变的时候,我要实时输出新的值*/ subscribe(() => { console.log(state.count); }); /*我们来修改下 state,当然我们不能直接去改...我们知道 reducer 是一个计划函数,接收老的 state,按计划返回新的 state。那我们项目中,有大量的 state,每个 state 都需要计划函数,如果全部写在一起会是啥样子呢?...counterReducer(state, action) { /*注意:如果 state 没有初始值,那就给他初始值!!...记录日志 我现在有一个需求,在每次修改 state 的时候,记录下来 修改前的 state ,为什么修改了,以及修改后的 state。...只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。

    63720
    领券