技术咨询、项目合作、广告投放、简历咨询、技术文档下载 点击这里 联系博主

# 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 保留的旧值的引用如果不是浅层相等的,组件就会被重新渲染。

【未经作者允许禁止转载】 Last Updated: 2/4/2024, 6:06:40 AM