多个setState方法的调用原理

React中通过使用setState来更新组件的状态,触发render

setState被调用时发生了什么?

React首先将你传递给setState函数的对象合并到当前状态中,然后创建一个React元素树,对比新旧树的差别,并根据你传递给setState函数对象的不同,计算出相应的变化部分,最终完成DOM更新

因为包含了大量的工作,调用setState可能并不会立即更新你的state,为异步的


如果在一个单独的函数中调用setState多余一次,React的处理方式?

React可能会出于性能的考虑,将多个setState调用合并成一个批处理更新操作

当遇到多个setState调用时,它会提取单次传递给setState的对象,把它们合并在一起形成一个新的单一的对象,并用这个单一的对象去做setState的事情

JS合并对象,可通过Object.assign()方法,且后一个key值会覆盖前面的key值

const a = {name : 'kong', age : '17'}
const b = {name : 'fang', sex : 'men'}
Object.assign({}, a, b);
//{name : 'fang', age : '17', sex : 'men'}
如果不想这样呢?试试函数式的setState

语法:

this.setState(function(state, props){
	return {
		name : state.name + ' hello'
	}
})
//该函数获取组件的上一次的状态和当前的属性,用于计算和返回下一个状态
此时,如果遇到多个setState的情况,它并不会把对象合并在一起,而是会按照调用的顺序排队,然后依次调用队列中的方法,把上一次的状态传递给当前的方法,从而不断的更新状态,这种处理方式很好的解决了,有些情况,需要通过上一次更新完的state来计算当前更新的state的值的时候,传递对象的方式因为异步,会有很大的隐患,所以使用函数式setState传递

changeStateThreeTest(){
	this.setState((state) => ({name : state.name + '1'}))
	this.setState((state) => ({name : state.name + '2'}))
	this.setState((state) => ({name : state.name + '3'}))
}

//React会把多个setState调用排列,可以想象成一个方法数组
const updateFunc = [
	(state) => ({name : state.name + '1'}),
	(state) => ({name : state.name + '2'}),
	(state) => ({name : state.name + '3'})
]
参考链接:

http://www.oschina.net/translate/functional-setstate-is-the-future-of-react

React中的setState自动批处理的实现原理是通过React的事务机制来实现的。 当调用setState时,React并不立即更新组件状态,而是将更新操作推入一个待处理队列中。在React的更新过程中,会涉及到多个生命周期函数的调用,事件处理函数的执行等操作。这些操作会触发组件状态的更新。 React会通过事务机制将这些更新操作进行批处理,以提高性能。事务机制可以确保在同一个事务中进行的多个setState调用会被合并为一个更新操作,而不会立即触发重新渲染。 具体的实现原理如下: 1. 当调用setState时,React会将更新操作添加到当前事务的待处理队列中。 2. React会检查当前是否有一个事务正在进行。如果没有,则创建一个新的事务。 3. 如果已经有一个事务在进行中,则将该更新操作添加到当前事务的待处理队列中。 4. 在事务结束之前,React会遍历待处理队列,并对其中的更新操作进行合并。它会将相同状态的更新操作进行合并,只保留最后一次的更新。 5. 事务结束时,React会触发重新渲染,并根据合并后的更新操作更新组件状态。 通过这种事务机制,React能够将多个setState调用进行批处理,减少不必要的重新渲染次数,提高应用的性能。同时,这种机制也确保了状态的更新是稳定的,并避免了因为多次调用setState而引发的不一致性问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值