[英]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。生产
好吧,即使我不确定这是不是正确的方法,我最终还是自己解决了这个问题。
发生的事情是我需要两件事:
也就是说,如果我们这样写:
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.