首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么immer.js不允许在草案中设置动态属性?

为什么immer.js不允许在草案中设置动态属性?
EN

Stack Overflow用户
提问于 2019-12-27 15:07:54
回答 1查看 4.7K关注 0票数 5

代码语言:javascript
复制
//I want my action to dispatch payload like
// {type:'update',payload:{'current.contact.mobile':'XXXXXXXXX'}}
//In reducer dynamically select the segment of state update needs to be applied to 
//Below code doesn't work as expected though, draft always remains at same level
draft = dA.key.split('.').reduce((draft, k) => {
  return draft[k]
}, draft);

//Or an ideal syntax may look like below line
draft['current.contact.mobile'] = dA.value;


//Code that works
draft['current']['contact']['mobile'] = dA.value;

我希望我的操作可以像{type:'update‘、payload:{'current.contact.mobile':'XXXXXXXXX'}}和reducer那样发送有效负载,动态地选择需要更新的状态段。做这件事有什么根本的错误吗,我相信这能让生活更轻松。有什么可以做到的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-30 18:12:30

在您的示例中,此代码像字符串或数字一样返回原始值,该字符串或数字是不可变的。

代码语言:javascript
复制
draft = dA.key.split('.').reduce((draft, k) => {
  return draft[k]
}, draft);

"Immer“是使用代理实现所有这些魔术。代理只能在对象、数组、函数等对象上工作。

因此,要解决问题,可以使用如下代码

代码语言:javascript
复制
import produce from "immer";

describe("Why immer.js doesn't allow setting dynamic properties on draft?", function() {
  it("should allow set dynamic properties", function() {
    const path = "foo.bar.zoo";
    const state = { foo: { bar: { zoo: 1 } } };
    const nextState = produce(state, draft => {
      const vector = path.split(".");
      const propName = vector.pop();

      if (propName) {
        draft = vector.reduce((it, prop) => it[prop], draft);
        draft[propName] += 1;
      }
    });

    expect(nextState.foo.bar.zoo).toEqual(state.foo.bar.zoo + 1);
  });
});

在上面的代码中,我们得到目标对象更新该对象的属性

一些关于字符串和数字的注释。Javascript和number有建设者,返回对象而不是原语值。但这是一个非常罕见的情况,当有人明确使用它。通常,我们在编写类似dA.key.split('.')的东西时都会隐式地处理它。在这种情况下,解释器将创建一个string对象,并在其上调用方法“拆分”。通常,这种行为被称为“拳击”。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59502573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档