为什么Redux中的对象应该是不可变的? 我知道一些框架如Angular2将使用onPush并且可以利用不变性来比较视图状态以便更快地呈现,但我想知道是否还有其他原因因为Redux是框架无关的,但它在自己的文档中提到使用不变性(无论框架如何)。
感谢任何反馈。
答案 0 :(得分:21)
Redux是一个小型库,它将状态表示为(不可变)对象。 新状态通过将当前状态传递给纯函数来创建一个全新的对象/应用程序状态。
如果你的眼睛瞪着那边不用担心。总而言之,Redux不会通过修改对象来表示应用程序状态的变化(就像使用面向对象的范例一样)。相反,状态更改表示为输入对象与输出对象(var output = reducer(input)
)之间的差异。如果您改变input
或output
,则会使州无效。
总结另一种方式,不变性是Redux的要求,因为Redux将您的应用程序状态表示为"冻结对象快照"。使用这些离散快照,您可以保存您的状态或反向状态,并且通常会有更多"记帐"所有州的变化。
您的应用的状态仅由名为reducers的纯函数类别更改。减速器有两个重要特性:
function name(state, action) {}
,因此可以轻松撰写:假设州看起来像这样:
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:
- Redux和React-Redux都使用shallow equality checking。特别是:
- Redux的combineReducers实用程序shallowly checks for reference changes由它调用的reducer引起。
- React-Redux的connect方法生成shallowly check reference changes to the root state的组件,以及mapStateToProps函数的返回值,以查看包装的组件是否确实需要重新呈现。这样shallow checking requires immutability能正常运作。
- 不可变数据管理最终使数据处理更安全。
- 时间旅行调试要求减速器是纯函数,没有副作用,因此您可以在不同状态之间正确跳转。
答案 2 :(得分:0)
改写文章https://medium.cobeisfresh.com/how-redux-can-make-you-a-better-developer-30a094d5e3ec
除了不可变数据外,纯函数也是核心概念之一 函数式编程
答案 3 :(得分:0)
Redux使用不变性的主要原因是它不必遍历对象树来检查每个键值的变化。相反,它只会检查对象的引用是否已更改,以便在状态更改时更新DOM。