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

时间:2016-01-23 02:01:46

标签: javascript angular reactjs redux immutability

为什么Redux中的对象应该是不可变的? 我知道一些框架如Angular2将使用onPush并且可以利用不变性来比较视图状态以便更快地呈现,但我想知道是否还有其他原因因为Redux是框架无关的,但它在自己的文档中提到使用不变性(无论框架如何)。

感谢任何反馈。

4 个答案:

答案 0 :(得分:21)

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

如果你的眼睛瞪着那边不用担心。总而言之,Redux不会通过修改对象来表示应用程序状态的变化(就像使用面向对象的范例一样)。相反,状态更改表示为输入对象与输出对象(var output = reducer(input))之间的差异。如果您改变inputoutput,则会使州无效。

总结另一种方式,不变性是Redux的要求,因为Redux将您的应用程序状态表示为"冻结对象快照"。使用这些离散快照,您可以保存您的状态或反向状态,并且通常会有更多"记帐"所有州的变化。

您的应用的状态由名为reducers的纯函数类别更改。减速器有两个重要特性:

  1. 他们永远不会改变,返回新构建的对象:这样可以推断输入+输出没有副作用
  2. 他们的签名始终 function name(state, action) {},因此可以轻松撰写:
  3. 假设州看起来像这样:

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

    我们想增加计数,所以我们制作这些减速器

    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 Objectd.assign({}, {_2ndLevel: _2ndlevel(state._2ndlevel)});
        }
    }
    

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

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

        dispatch({type: INCR_2ND_LEVEL_COUNT})
    

    ...... Redux将致电:

        theNewState = topLevel(theState, action);
    

    注意:action来自dispatch()

    现在theNewState全新对象

    注意:您可以使用a library(或new language features)强制执行不变性,或者只是注意不要改变任何内容:D

    为了更深入一点,我强烈建议您通过Dan Abramov(创作者)结帐this video。它应该回答你有任何挥之不去的问题。

答案 1 :(得分:9)

Redux文档中提到了以下benefits of immutability

  

答案 2 :(得分:0)

改写文章https://medium.cobeisfresh.com/how-redux-can-make-you-a-better-developer-30a094d5e3ec

  

除了不可变数据外,纯函数也是核心概念之一   函数式编程

答案 3 :(得分:0)

Redux使用不变性的主要原因是它不必遍历对象树来检查每个键值的变化。相反,它只会检查对象的引用是否已更改,以便在状态更改时更新DOM。