javascript - 为什么 Redux 中的对象应该是不可变的?

标签 javascript angular reactjs redux immutability

为什么 Redux 中的对象应该是不可变的? 我知道某些框架(例如 Angular2)将使用 onPush 并且可以利用不变性来比较 View 状态以加快渲染速度,但我想知道是否还有其他原因,因为 Redux 与框架无关,但它在自己的文档中提到要使用不变性(无论框架如何)。

感谢任何反馈。

最佳答案

Redux 是一个将状态表示为(不可变)对象的小型库。 新状态通过纯函数传递当前状态来创建全新的对象/应用程序状态。

如果您在那里的眼睛呆滞,请不要担心。总而言之,Redux 不会通过修改对象来表示应用程序状态的变化(就像您在面向对象的范例中所做的那样)。相反,状态变化表示为输入对象和输出对象之间的差异 (var output = reducer(input))。如果您改变 inputoutput 您会使状态无效。

换句话说,不变性是 Redux 的一项要求,因为 Redux 将您的应用程序状态表示为“卡住对象快照”。使用这些离散快照,您可以保存您的状态或反转状态,并且通常对所有状态更改有更多的“说明”。

您的应用程序的状态由一类称为缩减器的纯函数更改。 reducer 有两个重要的属性:

  1. 它们从不改变,返回新构建的对象:这允许对输入+输出进行推理没有副作用
  2. 它们的签名总是 function name(state, action) {},因此很容易组合它们:

假设状态是这样的:

    var theState = {
      _2ndLevel: {
        count: 0
      }
    }

我们想增加计数,所以我们制作了这些 reducer

const INCR_2ND_LEVEL_COUNT = 'incr2NdLevelCount';

function _2ndlevel (state, action) {
    switch (action.type) {
        case INCR_2ND_LEVEL_COUNT:
            var newState = Objectd.assign({}, state);
            newState.count++
            return newState;
        }
    }

function topLevel (state, action) {
    switch (action.type) {
        case INCR_2ND_LEVEL_COUNT:
            return Object.assign(
                {}, 
                {_2ndLevel: _2ndlevel(state._2ndlevel, action)}
            );
    }
}

注意使用 Object.assign({}, ...)each reducer 中创建一个全新的对象:

假设我们已经将 Redux 连接到这些 reducer,那么如果我们使用 Redux 的事件系统来触发状态更改......

    dispatch({type: INCR_2ND_LEVEL_COUNT})

...Redux 将调用:

    theNewState = topLevel(theState, action);

注意:action 来自 dispatch()

现在 theNewState 是一个全新的对象

注意:您可以使用 a library 强制不变性(或 new language features ),或者小心不要改变任何东西 :D

为了更深入地了解,我强烈建议您查看 this video由 Dan Abramov(创作者)创作。它应该可以回答您的任何挥之不去的问题。

关于javascript - 为什么 Redux 中的对象应该是不可变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34958775/

相关文章:

css - 垂直滚动时下拉内容固定在屏幕上

javascript - 如何在 Promise 中获取数据数组

javascript - 为什么 jQuery.load 不适用于该页面?

javascript - 如何在d3中的平行坐标图中为线条着色?

javascript - jQuery 翻转不透明度变化

angular - 相当于 Angular 中 APP_INITIALIZER 的模块

Angular APP_INITIALIZER 提供程序将一项注入(inject)服务视为未定义,但其他服务注入(inject)得很好

angular - 如何使用值时间戳过滤 Angular Material 表字段?

javascript - 功能组件中的 setState 不保留值

javascript - Node.js 中不必要的回调使用?