Immutability in React

October 25, 2022

就像它描述的这样,不可变「immutability」就意味着数据本身是不可以被修改的

目的

在 React 中为什么要使用不可变数据呢?

  • React 中组件的更新是依赖状态有无更新的。不可变数据会让 React 状态值在每次更新时都返回一个全新的值,这样对于引用数据类型的更新判断就变的非常容易
  • 不可变数据也会让数据更容易预测与维护,避免数据在某处不小心被修改而导致 bug

问题

不可变性提供了很多便利,但是在更新复杂值时会变的非常麻烦,例如

const initialState = {
  phone: '1-770-736-8031 x56442',
  website: { site: 'hildegard.org' },
  company: {
    name: 'Romaguera-Crona',
    catchPhrase: 'Multi-layered client-server neural-net',
    bs: 'harness real-time e-markets',
    money: {
      type: 'RMB'
      total: 1111111
    }
  }
}
// 如果要更新 total
setState({
  ...initialState,
  company: {
    ...initialState.company,
    money: {
      ...initialState.company.money,
      total: 2222222
    }
  }
})

从上面可以看到,我们为了生成新数据写法非常麻烦,为了清晰我们可以每次深拷贝对象,然后再修改对应的值。这样代码是清晰了,但是也会增加无用的拷贝,而且对于引用类数据类型还会生成一个全新的引用类型数据,从而导致其他组件的更新

解决方案

如果使用 immer,我们写起来是这样的

setState((prevState) => {
	produce(prevState, (draft) => {
  	draft.company.money.total = 2222222
  })
})

非常的简单与清晰,而且 immer 在内部做了很好的性能优化。那 immer 是如何实现的呢?

实现

immer.js 的动机就是要让 js 对于复杂对象的修改变得更加容易、高效。