首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使过滤器与Immer.js一起工作以删除数组中的嵌套对象

无法使过滤器与Immer.js一起工作以删除数组中的嵌套对象
EN

Stack Overflow用户
提问于 2021-02-11 15:48:36
回答 3查看 1.9K关注 0票数 3

我从Immer.js开始讨论JS中的不可变性,而我无法找到一种使用过滤器方法删除数组中的对象的方法。它返回相同的对象。顺便说一句,我是在与状态做出反应,但为了使它更加简单,我编写了反映我的问题的简单片段。

代码语言:javascript
复制
const sampleArr = [
      {
        items: [
          { slug: "prod1", qnty: 1 },
          { slug: "prod2", qnty: 3 },
          { slug: "prod3", qnty: 2 },
        ],
      },
    ];
    
    const newState = produce(sampleArr, (draft) => {
      draft[0].items.filter((item) => item.slug !== "prod1");
    });
    
    console.log(newState);

Console.log应该给出相同的数组,但没有第一项。但是,我得到的是相同的数组,没有任何改变的

我在谷歌上搜索了它,搜索了immer文档,但是找不到我的答案。关于阵列突变Immer.js => https://immerjs.github.io/immer/docs/update-patterns的文档

大胸。要在chrome工具上测试它,可以复制粘贴immer (https://unpkg.com/immer@6.0.3/dist/immer.umd.production.min.js)并将生成方法更改为immer.produce。

EN

回答 3

Stack Overflow用户

发布于 2022-02-14 09:01:35

使用析构使不可变对象与Immert相反。解决这一问题的方法是将过滤后的部分重新分配到草案中。解决方案如下:

代码语言:javascript
复制
const sampleArr = [
  {
    items: [
      { slug: "prod1", qnty: 1 },
      { slug: "prod2", qnty: 3 },
      { slug: "prod3", qnty: 2 },
    ],
  },
];

const newState = produce(sampleArr, (draft) => {
  draft[0].items = draft[0].items.filter((item) => item.slug !== "prod1");
});

您可以在下面的回复中四处游玩:https://replit.com/@GaborOttlik/stackoverflow-immer#index.js

票数 1
EN

Stack Overflow用户

发布于 2021-02-11 17:55:57

嗯,我自己解决了这个问题,尽管我不确定这是不是正确的方法。

我需要两样东西:

  1. 函数返回,复制其余的属性并将它们添加到新的返回

也就是说,如果我们这样写的话:

代码语言:javascript
复制
const newState = produce(sampleArr, (draft) => {
    return draft[0].items.filter((item) => item.slug !== "prod1");
});

我们返回过滤后的项数组

代码语言:javascript
复制
[
    { slug: "prod2", qnty: 3 },
    { slug: "prod3", qnty: 2 },
]

然而,它需要添加回其余的属性。假设你有更多的数据等等,所以我喜欢这样:

代码语言:javascript
复制
const newState = produce(sampleArr, (draft) => {
    draft = [
        ...draft.slice(0,0),
        {
            ...draft[0],
            draft[0].items.filter((item) => item.slug !== "prod1"),
        }
        ...draft.slice(1)
    ];
    return draft;
});

编辑=================================================

发现它不需要做我上面做的所有事情。我本可以像我第一次那样做。只是缺少任务。

draft[0].items = draft[0].items.filter((item) => item.slug !== "prod1");

票数 0
EN

Stack Overflow用户

发布于 2021-11-24 22:31:29

您遇到的问题是Immer不允许您同时修改草案并从产品中返回一个全新的值。这样做将产生以下在this question下详细讨论的错误

错误:一个immer生产者返回一个新值并修改了它的草稿。返回一个新值或修改草案

作为纯粹的推测,我想这是故意不允许的,因为这几乎总是一个bug,除了这个特定的用例。

为了避免这个问题,您可以做的是将要在临时对象中处理的数组包装起来,然后在检索结果时销毁该对象:

代码语言:javascript
复制
const { newArray } = produce({ newArray: oldArray }, (draft) => {
  // Filtering works as expected
  draft.newArray = draft.newArray.filter(...);

  // Modifying works as expected
  if (draft.newArray.length) {
    draft.newArray[0].nested.field = ...;
  }

  // No return statement
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66158052

复制
相关文章

相似问题

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