感谢任何反馈。
Redux是一个小型的库,将状态表示为(不可变)对象。通过纯函数将当前状态传递来创建全新的对象/应用程序状态,从而产生新状态。
如果您感到有些困惑,不用担心。简而言之,Redux不通过修改对象来表示应用程序状态的更改(如面向对象编程所做的那样)。相反,状态更改表示为输入对象和输出对象(var output = reducer(input)
)之间的差异。如果您改变或
用另一种方式来概括,Redux需要不可变性,因为它将您的应用程序状态表示为"冻结的对象快照"。通过这些离散的快照,您可以保存状态或撤消状态,并且通常对所有状态更改都有更多的"控制"。
你的应用程序的状态仅由被称为reducer的一类纯函数更改。Reducer具有两个重要属性:
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)}
);
}
}
请注意在每个reducer中使用Object.assign({}, ...)
来创建全新的对象:
假设我们已经将Redux连接到这些reducers,那么如果我们使用Redux的事件系统来触发状态更改...
dispatch({type: INCR_2ND_LEVEL_COUNT})
...Redux 会调用:
theNewState = topLevel(theState, action);
注意: action
是来自于 dispatch()
现在,theNewState
是一个全新的对象。
请注意:您可以使用库(或新的语言特性)强制实现不可变性,或者只需小心不要改变任何东西:D
如果想深入了解,我强烈推荐您查看这个视频,由创建者Dan Abramov制作:video链接。它应该回答您所拥有的任何问题。
在 Redux 文档中提到了以下不可变性的好处:
- Redux 和 React-Redux 都采用浅相等检查。特别地:
- Redux 的 combineReducers 工具浅层检查由其调用的 reducer 引起的引用更改。
- React-Redux 的 connect 方法生成的组件浅层检查根状态和 mapStateToProps 函数的返回值,以查看是否需要重新渲染包装的组件。这种浅层检查需要使用不可变性才能正常工作。
- 不可变数据管理最终使数据处理更加安全。
- 时光旅行式调试要求 reducer 是纯函数,没有副作用,这样您就可以在不同的状态之间正确跳转。
state
会干扰“应该组件更新”的逻辑吗?能否说明会以何种方式出错,例如始终/从不/取决于什么? - bluenote10combineReducers
和/或 react-redux
。如果你更深入地了解 combineReducers
和 react-redux
,你肯定可以知道会发生什么。通常情况下,当由于浅层检查而未检测到深层更改时,你的 UI 中的某些组件将不会更新。但最重要的是——不要改变状态。这是一件坏事™。 - Andrea Casacciareact
+mobx
或vue.js
的内容。 - puchuRedux使用不可变性的主要原因是它不必遍历对象树来检查每个键值的更改。相反,它只会检查对象的引用是否已更改以便在状态更改时更新DOM。
优秀的文章 https://medium.cobeisfresh.com/how-redux-can-make-you-a-better-developer-30a094d5e3ec
不可变数据和纯函数是函数式编程的核心概念之一。
根据官方文档:
在Redux中,有几个原因说明为什么不能改变状态: