我要在此React Hooks Reducer中处理状态更新吗?

时间:2019-02-28 02:03:12

标签: reactjs react-redux immutability react-hooks

在以下代码片段中,我有一个工作正常的reducer,我认为这是不正确的,因为它正在重用现有状态而不是替换它。它确实可以正常工作,但没有出现与我有关的错误。

  1. 不需要Object.assign是否正确?
  2. 假设它不正确会出现错误吗?
  3. 有什么工具可以帮助我验证状态更新的正确性?

进入这个化简器的状态只是一个只有第一级对象的简单数组。也就是说,像这样:

const stateIn = [{id: 101,favorite: 0},{id: 102,favorite: 1},...]

我怀疑的减速器如下:

  const speakersReducer = (state, action) => {
    switch (action.type) {
      case "loadspeakers": {
        return action.data;
      }
      case "favorite": {
        return state.map((item, index) => {
          if (item.id === action.sessionId) {
            // let speakerToUpdate = Object.assign(item);
            // speakerToUpdate.favorite = 1;
            item.favorite = 1;
            return item;
            // return speakerToUpdate;
          }
          return item;
        });
      }
      ...
      default:
        return state;
    }
  };
  export default speakersReducer;

1 个答案:

答案 0 :(得分:0)

  

这正确吗?

正如@Tholle所指出的,item中的"favorite"突变确实是可疑的。减速器中的突变通常被认为是一种反模式,并且经常会导致错误。我绝对建议将其更改为不可变模式。

但是然后...

  

假设不正确,为什么这不会导致错误?

Reducer中的可变性是常见的错误来源,但是特定的突变位是否会引起错误,取决于其突变方式以及Reducer的使用方式。

尽管收藏夹情况可能会错误地将item对象从状态的一个版本重用到另一状态,但由于Array.prototype.map总是返回一个新的数组,因此它总是产生一个新的状态数组。因此,例如,useReducer仅关心外部状态对象的身份,尽管发生了突变,它仍将正确触发重新渲染。

另一方面,记忆在数组中特定项目上的redux选择器会错误地返回旧值。而且,如果将旧的items缓存并重新使用,则该突变也可能在此引起意外错误。但是这些是相当具体的情况,因此在大多数情况下,我怀疑这是可行的。 (不过,我仍然会将其更改为不变异)

  

有什么工具可以帮助我验证状态更新的正确性吗?

您想要的是某种形式的不变性:JS中有许多用于不变性的库。

  • ImmutableJS用自己的API定义自己的数据结构
  • seamless-immutable定义了看起来像普通可变结构的不可变数据结构
  • immer使您可以使用普通的可变操作语法进行不可变的操作。

还可以单独使用Typescript,也可以将它们与这些库结合使用:允许将对象和数组声明为只读,并且如果对它们进行更改会引起编译器错误。

linter规则也可能会有所帮助,但除非您可以禁止整个代码库中的所有变异,否则手动操作精简器中的规则,否则将非常棘手。