setState更新数据的合并
State 的更新会被合并
当你调用 setState()
的时候,React 会把你提供的对象合并到当前的 state。
例如,你的 state 包含几个独立的变量:
constructor(props) { |
然后你可以分别调用 setState()
来单独地更新它们:
componentDidMount() { |
这里的合并是浅合并,所以 this.setState({comments})
完整保留了 this.state.posts
, 但是完全替换了 this.state.comments
。
源码
react-reconciler -> ReactUpdateQueue.old.js -> processUpdateQueue
这个processUpdateQueue
就是用来计算状态更新的方法。
可以看到这个方法从workInProgress
取出了updateQueue
,这个updateQueue就是上一次文章中提到的保存了update对象的队列。
这个方法中又调用了一个getStateFromUpdate方法,这个方法就会根据updateQueue计算State。
可以从下面的源码中看到:
React源码中,使用了Object.assign()
方法,对preState和更新后的State做了一个合并。
同时,update.payload
就是我们传递给setState的参数。
React会对参数做一个判断:
- 如果传入的是一个
function
就会执行这个函数,获得对应的State。 - 如果不是函数(一般都是一个对象),React会直接将它赋值给partialState,也就是newState。
因此,如果多次传入相同的对象,如:
this.state = { counter: 0 }; |
原因就是每次拿到的partialState
都是 { counter: 0 }, 然后对它们做合并操作, 最后还是 { counter: 1 },
所以如果想完成上面的操作,需要给setState传入函数, 从源码中可以看到,函数可以接受到两个参数,一个是上一次的prevState,一个是nextProps
this.state = { counter: 0 }; |
参考:
Reat源码17.0.2
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 袁光斌的Blog!
评论