# 1. setState的用法概括
setState的3种用法
用法1:setState的第二参数 回调函数,会等到setState状态异步更新完毕且真实dom被渲染完毕,此时可以拿到最新的状态值
用法2:三个同key值的操作会被合并处理,只取最后一个的setState,最后一个覆盖之前的
用法3:setState的第一个参数是回调函数,该回调函数有一个参数prevstate是之前的状态,多个setState会被加到一个队列中,前一个更新到dom中,才会执行下一个,且同步完成
用法4:在setTimout或者原生事件中,setState是同步的
# 2. setState的3种用法
import React from 'react'
class App extends React. Component{
state = {
count: 0
}
render() {
return <div>
{this.state.count}
<button onClick = {this.handleCount1}>click-1</button>
<button onClick = {this.handleCount2}>click-2</button>
<button onClick = {this.handleCount3}>click-3</button>
</div>
}
}
export default App
# 2-1 用法1(第二个参数 回调函数取得最新的状态值)
handleCount1 = () => {
// setState 用法1
this. setState({
count: this.state.count + 1
}, () => {
console.log(this.state.count) // 此时访问的是真实的dom,dom已经渲染完毕
})
}
setState的第二参数 回调函数,会等到setState状态异步更新完毕且真实dom被渲染完毕,此时可以拿到最新的状态值
# 2-2 用法2(三个同key值的操作会被合并处理)
handleCount2 = () => {
this. setState({
count: this.state.count + 1
})
this. setState({
count: this.state.count + 1
})
this. setState({
count: this.state.count + 5
})
console. log(this. state. count) // 5
}
三个同key值的操作会被合并处理,只取最后一个的setState,最后一个覆盖之前的
# 2-3 用法3(加入队列,后一个等前一个限制性完成,同步)
handleCount3 = () => {
this. setState((prevstate) => ({
count: prevstate.count +1
}))
this. setState((prevstate) => ({
count: prevstate.count +1
}))
this. setState((prevstate) => ({
count: prevstate.count +1
}))
console. log(this. state. count) // 3
}
setState的第一个参数是回调函数,该回调函数有一个参数prevstate是之前的状态,多个setState会被加到一个队列中,前一个更新到dom中,才会执行下一个,且同步完成
细节补充
function test() {
return {
name: "kerwin"
}
}
错误写法 {} 里包含的应该是函数体,不符合js语法
var test2 = () => {
name: "kerwin"
}
正确写法
var test2 = () => ({
name: "kerwin"
})
# 2-4 用法5(在setTimeout事件中,同步)
handleCount4 = () => {
this. setState({
count: this.state.count + 1
})
console. log(this. state. count) // 0
setTimeout(_ => {
this.setState({count: this.state.count + 1})
console.log(this.state.count) // 2
}, 2000)
setTimeout(_ => {
this.setState({count: this.state.count + 1})
console.log(this.state.count) // 3
}, 2000)
}
在setTimout或者原生事件中,setState是同步的
# 3. setState的后发生了什么?setState为什么默认是异步?setState什么时候是同步?
# 3-1 setState的后发生了什么?
- setState之后,React会将传入的参数对象和当前的状态合并,重新构建React元素树并且重新渲染整个UI界面。
- React会生成新的虚拟dom,与老的dom节点进行对比diff算法对比,以最小的代价更新真实dom,重新渲染。
- 在diff算法比对中,React能够精确的知道哪些位置发生了变化,以及如何改变,这就保证了按需更新,而不是全部重新渲染。
# 3-2 setState为什么默认是异步?
- 加入所有的setState都是同步的,意味着每执行一次setState时,都重新虚拟dom diff算法对比真实dom,这对性能来说是极为不好的。
- 如果是异步,则可以把一个同步代码中的多个setState合并称一次组件更新
# 3-3 setState什么时候是同步?
在setTimout或者原生事件中,setState是同步的
# 4. 多次调用setState 会不会对性能产生影响?
不会,三个同key值的操作,会被合并处理,以最后一个为主,最后一个会覆盖之前的