在数组 redux 中更新数组

Updating array within array redux

我有一个嵌套数组的状态,如下所示:

{
    list: [
        {
        id: '3546f44b-457e-4f87-95f6-c6717830294b',
        title: 'First Nest',
        key: '0',
        children: [
            {
            id: '71f034ea-478b-4f33-9dad-3685dab09171',
            title: 'Second Nest',
            key: '0-0
            children: [
                {
                id: '11d338c6-f222-4701-98d0-3e3572009d8f',
                title: 'Q. Third Nest',
                key: '0-0-0',
                }
            ],
            }
        ],
    ],
    selectedItemKey: '0'
}

嵌套数组的目标是模拟树,selectedItemKey/key 是如何快速访问树节点。

我编写了代码以使用以下逻辑更新嵌套项的标题:

let list = [...state.list];
let keyArr = state.selectedItemKey.split('-');
let idx = keyArr.shift();
let currItemArr = list;

while (keyArr.length > 0) {
  currItemArr = currItemArr[idx].children;
  idx = keyArr.shift();
}

currItemArr[idx] = {
  ...currItemArr[idx],
  title: action.payload
};

return {
  ...state,
  list
};

第一个嵌套项目工作正常,但对于第二和第三级嵌套,我收到以下 Immer 控制台错误

An immer producer returned a new value *and* modified its draft.
Either return a new value *or* modify the draft.

关于我的嵌套数组 access/update 逻辑,或者我试图制作 state.list 的新副本的方式,我觉得我在这里搞砸了一些相当大的事情并修改它。请注意嵌套级别是动态的,在修改之前我不知道它的深度。

再次感谢!

Immer 允许您修改现有草稿 statereturn 新状态,但不能同时修改两者。

看起来你正在尝试 return 一个新的状态,只要没有突变就可以。但是,您在分配 currItemArr[idx] = 时进行了修改。这是一个突变,因为 listcurrItemArr 的元素与 state.list 中的元素相同。这是一个“浅拷贝”。

但是您不必担心浅拷贝和突变,因为更简单的方法是只修改草稿状态而不是 return 任何东西。

您只需找到正确的对象并设置其 title 属性。我想出了一个更短的方法来使用 array.reduce().

const keyArr = state.selectedItemKey.split("-");

const target = keyArr.reduce(
  (accumulator, idx) => accumulator.children[idx],
  { children: state.list }
);

target.title = action.payload;