【问题标题】:What are the consequences of mutating state in a reducer?在 reducer 中改变状态的后果是什么?
【发布时间】:2018-02-15 12:11:15
【问题描述】:

redux 指南指出:

我们不会改变状态。我们使用 Object.assign() 创建一个副本。 Object.assign(state, { visibilityFilter: action.filter }) 也是错误的:它会改变第一个参数。您必须提供一个空对象作为第一个参数。您还可以启用对象扩展运算符提案以改为编写 { ...state, ...newState }。

我碰巧发现自己正在编写以下工作代码的 sn-p:

[actions.setSelection](state, {payload}) {
    state[payload.key] = payload.value;
    return state;
},

我对此有一种不好的感觉,并重新访问了智慧指南。此后我将其重写为:

[actions.setSelection](state, {payload}) {
    const result = Object.assign({}, state);
    result[payload.key] = payload.value;
    return result;
},

我很确定我在代码中的其他地方触犯了上述诫命。如果不努力追踪他们,我会考虑什么样的后果?

(注意:上面的 reducer 语法是通过 redux-actions 实现的。否则它将是 reducer fn switch/case 中的代码块。)

【问题讨论】:

  • 我相信如果你在你的 reducer 中改变状态,当一个动作被调用时你的组件不会重新渲染。

标签: react-redux


【解决方案1】:

突变状态是 React 中的一种反模式。 React 使用渲染引擎,它依赖于状态变化是可观察的这一事实。这个观察是通过比较前一个状态和下一个状态来进行的。它将使用差异更改虚拟 dom,并将更改的元素写回 dom。

当你改变内部状态时,React 不知道发生了什么变化,甚至更糟;它对当前状态的概念是不正确的。所以 dom 和 virtual dom 会变得不同步。

Redux 使用相同的想法来更新它的存储;计算存储的下一个状态的减速器可以观察到一个动作。更改被发出,例如被 react-redux connect 消耗。

简而言之:永远不会改变状态。您可以使用 stage-3 展开语法来代替 Object.assign:

{...previousState,...changes}

另外请注意,数组也是如此!

【讨论】:

  • 谢谢你。它有助于解释我在使用 redux 时看到的症状。我想我现在可以看到,通过直接改变传递给我的 reducer 的参数“状态”,我正在从 redux(和 React)下面拉出地毯,以确定状态是否已经改变。 ...我有一些减速器要清理。
猜你喜欢
  • 2017-10-01
  • 1970-01-01
  • 2021-09-07
  • 2019-02-03
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多