繁体   English   中英

无法使过滤器与 Immer.js 一起使用以删除数组中的嵌套 object

[英]Can't make filter work with Immer.js to remove nested object in array

我从 Immer.js 开始在 JS 中实现不变性,但我找不到使用 filter 方法删除数组中的 object 的方法 它返回相同的 object。 顺便说一句,我正在使用 state 在 React 中进行此操作,但为了使其更简单,我制作了反映我的问题的简单片段。

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。生产

好吧,即使我不确定这是不是正确的方法,我最终还是自己解决了这个问题。

发生的事情是我需要两件事:

  1. 从产品返回 function
  2. 复制属性的rest,添加到新的return

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

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

我们取回过滤后的项目数组

[
    { slug: "prod2", qnty: 3 },
    { slug: "prod3", qnty: 2 },
]

但是,需要重新添加属性的 rest。 假设您有更多数据等。所以我这样做了:

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");

您遇到的问题是 Immer 不允许您修改草稿并从产品中返回全新的值。 这样做将产生以下错误,该错误将在此问题下进一步详细讨论:

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

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

为了回避这个问题,您可以做的是将要使用的数组包装在临时 object 中,然后在检索结果时破坏该 object:

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
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM