一、状态延迟更新
代码如下(示例):
class TestComp extends Component {
state = {
count: 0
}
render() {
return (
<div>
{this.state.count}
<button onClick={() => {
this.setState({
count: this.state.count + 1
})
this.setState({
count: this.state.count + 1
})
this.setState({
count: this.state.count + 1
})
// 结果是多少?
console.log(this.state.count) //1
}}>累加</button>
</div >
)
}
}
连续调用this.setState({…}),不会达到累加的效果。
react框架内部对setState进行了类似防抖的优化,一段时间内多次更新状态,执行最后一次。
二、连续调用的推荐写法
在setState()中传入函数 (oldState) => { return { .....}}
代码如下(示例):
class TestComp extends Component {
state = {
count: 0
}
render() {
return (
<div>
{this.state.count}
<button onClick={() => {
// 真正连续执行三次的写法
this.setState((oldState) => {
return {
count: oldState.count + 1
}
})
this.setState((oldState) => {
return {
count: oldState.count + 1
}
})
this.setState((oldState) => {
return {
count: oldState.count + 1
}
})
// 结果是多少?
console.log( this.state.count); // 3
}}>累加</button>
</div>
)
}
}
上面代码中的连续调用,每个调用都会被执行,但不会做多次渲染操作,而只会在最后一次调用后执行一次渲染。
三、第二个参数
setState()的第二个参数是回调函数,在状态更新之后执行
- 表现出异步的行为,但不是异步
(不是异步,不是异步,不是异步)
,仍是同步的!!! - 因为 React 在框架内部,做了优先级优化处理,调整了语句的执行顺序,但是执行还是同步的
代码如下(示例):
// ...
<button onClick={() => {
state = {
count: 0
}
this.setState((oldState) => {
return {
count: oldState.count + 1
}
}, () => {
console.log('setState中的第二个参数打印', this.state.count); // 1 后打印
})
console.log('>>>>>', this.state.count);// 0 先打印
}}>累加</button>
// ...
四、 同步?异步?行为
注意:
-
首先声明setState 是同步的
,只是表现行为有‘同步’和‘异步’ -
React 17 及之前的,setState 在定时器
setTimeout/setInterval
或原生事件监听函数
中被调用,表现出“同步”的行为; -
React 18 中,setState 在定时器
setTimeout/setInterval
或原生事件监听函数
中被调用,仍然表现为“异步”行为 -
在所有的版本中,
setState
如果在生命周期钩子函数
或React的事件处理函数(合成时间处理函数)
中被调用,则表现为“异步”
总结
以上是初学react的一点笔记,如有不足之处还请指正。