# Redux为什么要求数据不可变
不可变数据就是你不能直接修改它的值,而是通过复制它的值,并且产生一个新对象的方式来得到一个新的数据,包含里要修改的部分。
# Redux 为何需要不可变数据
# 1.性能优化
因为当 store 发生变化的时候,我们需要通知所有的组件进行更新。
# store 如何发生变化?
在 Redux 中,所有的变化都是由 action 触发的,action 触发在原来旧的 state 上,形成一个新的 state。 这两个新旧 state,是完全不同的对象。 当旧的 state 和新的 state 不是同一个对象时,我们就知道这个 store 发生了变化,我们不需要比较它其中的值有没有发生变化,我们只需要比较两个引用的状态是不是一样(浅比较)。所以通过这种不可变的机制达到性能优化的目的。
# Redux 中的 store 是不可变的。每个节点都是不可变数据。
这样,当一个组件绑定在一个节点上。我们只要判断前一个状态和后一个状态它们是否相等,就能知道当前的 store 有没有发生变化。从而决定是否更新组件。 这样就不要去做深层次的遍历每个值是否相等,而只是通过比较引用是否是同一个就可以达到目的。
# 2.易于调试和跟踪
当你的 store 发生变化的时候,在任何时刻都可以记录之前的状态和之后的状态。并且计算它们 diff 的值。
# 3.易于推测
在任何时刻都可以推测 store 是由什么引起的变化。store 一定是触发了 action 才会变化。 通过比较 action 之前的状态是什么,之后的状态是什么,可以很容易地判断当前的 action 是否被正确处理。
# 4. 不可变数据的管理极大地提升了数据处理的安全性。
# react-redux 是如何使用浅比较来决定组件是否需要重新渲染的?
每次调用 React-Redux
提供的 connect
函数时,它储存的根 state 对象的引用,与当前传递给 store
的根 state
对象之间,会进行浅比较。如果相等,说明根 state 对象没有变化,也就无需重新渲染组件,甚至无需调用 mapStateToProps
。
如果发现其不相等,说明根 state 对象已经被更新了,这时 connect
会调用 mapStateToProps
来查看传给包装的组件的 props 是否被更新。
它会对该对象的每一个值各自进行浅比较,如果发现其中有不相等的才会触发重新渲染。
在下例中,调用 connect
后,如果 state.todos
以及 getVisibleTodos()
的返回值没有改变,组件就不会重新渲染。
function mapStateToProps(state) {
return {
todos: state.todos, // prop value
visibleTodos: getVisibleTodos(state) // selector
}
}
export default connect(mapStateToProps)(TodoApp)
与之相反,在下例中,组件总是重新渲染,因为不管 todos
的值有没有改变,todos
本身总是一个新的对象。
// AVOID - will always cause a re-render
function mapStateToProps(state) {
return {
// todos always references a newly-created object
todos: {
all: state.todos,
visibleTodos: getVisibleTodos(state)
}
}
}
export default connect(mapStateToProps)(TodoApp)
mapStateToProps
返回的新值,与 React-Redux 保留的旧值的引用如果不是浅层相等的,组件就会被重新渲染。
- 本文链接: https://mrgaogang.github.io/react/Redux%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E6%B1%82%E6%95%B0%E6%8D%AE%E4%B8%8D%E5%8F%AF%E5%8F%98.html
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!