javascript - (React) Redux 状态未过滤

如果项目的布尔属性 value 更改,我可以更改列表中的项目,我的列表会更新。但是,如果我尝试更改字符串属性并返回有效负载,我的列表不会更新。

这在我直接更改项目并将其退回时有效。

case UPDATED_LISTITEM:
  let newList = state.list.filter((item) => {
    if (item._id !== payload._id) {
      return item;
    } else {
      item.title = payload.title;
      item.checked = payload.checked;
      return item;
    }
  });

  return {
    ...state,
    list: newList,
  };

当我尝试返回有效负载并且只更新“标题”时,这不起作用。如果我更新“已检查”,则状态会正确返回。

case UPDATED_LISTITEM:
  return {
    ...state,
    list: state.list.filter((item) => {
      if (item._id !== payload._id) {
        return item;
      } else {
        return payload;
      }
    }),
  };

回答1

这里有几个不同的问题。

一是这段代码正在改变 item,而在使用 Redux 时这是不允许的:

item.title = payload.title;
item.checked = payload.checked;

Redux 需要不可变的更新,这意味着总是制作数据的副本。

另一个是您使用了错误的数组方法。您正在调用 list.filter(),但您总是返回项目。我认为您想改用 list.map()

除此之外,恐怕您正在编写的 Redux 代码的风格已经过时了。看起来您正在“手写”您的减速器、不可变更新和操作类型。

今天,我们使用 Redux Toolkit 和 React-Redux 钩子 API 教授“现代 Redux”,这更易于学习和使用。您正在编写的代码将运行,但它需要编写至少 4 倍的代码,并且会更加混乱。

我强烈建议阅读我们的官方 Redux 文档教程,其中将 Redux 工具包和 React-Redux 钩子作为标准方法进行了介绍:

https://redux.js.org/tutorials/index

回答2

不改变状态的版本:

case UPDATED_LISTITEM:
  return {
    ...state,
    list: state.list.map((item) => ({
      ...item, // item must not contain more deeply nested objects!

      // Update title and checked from payload
      ...(
        item._id === payload._id ?
          { title: payload.title, checked: payload.checked } : {}
      )
    }),
  };

正如另一个答案所述,使用 redux 工具包更容易。旧方法涉及仔细重构状态,大量使用扩展运算符 (...)。深度嵌套的对象容易出错。

相似文章

最新文章