React中的setState异步回调和同步

在使用React过程中,可以使用this.state来访问需要的某些状态,但是需要更新或者修改state时,一般而言,我们都会使用setState()函数,从而达到更新state的目的,setState()函数执行会触发页面重新渲染UI。

异步与回调

首先,需要我们注意的是,setState函数是“异步”的。在它立即执行后,无法获取最新的state值。这是因为React对state的所有改变进行合并处理之后,才会去计算新的虚拟dom,再根据最新的虚拟dom去重新渲染真实dom。

1. 回调:

setState(updater[, callback])  //

updater是要改变的state对象,callback是state导致的页面重新渲染的回调,等价于componentDidUpdate

2. 区别:

//不使用回调
this.state = {preState: false};
this.setState({preState: true});
console.log(this.state.preState); // false

//使用回调
this.state = {newState: false};
this.setState(
	{
		newState: true
	}, ()=> {
	    console.log(newState); // true
	}
);

同步

其次,我们需要了解的是,setState并不是真正的“异步”。它只是模拟了异步行为,在React中会维护一个isBatchingUpdates标识,用来标记更新行为,依此判断是直接更新还是暂存state。在onClickonChange等React合成事件中,state会被控制在合成事件和钩子函数执行之后更新,因此在合成事件和钩子函数中无法拿到最新的值(在回调中可以拿到),形成了所谓的“异步”。

那在什么场景下,它是同步的呢?

1. 原生事件中

class App extends Component {

  state = { count: 0 }

  change = () => {
    this.setState({ count: this.state.count + 1 })
    console.log(this.state.count)  // 1
  }

 componentDidMount() {
    document.body.addEventListener('click', this.change, false)
 }
 
  render() {
    return (
      <div>
        {`Count is: ${this.state.count}`}
      </div>
    )
  }
}

2. setTimeout中

class App extends Component {

  state = { count: 0 }

 componentDidMount() {
    setTimeout(() => {
      this.setState({ count: this.state.count + 1 })
      console.log(this.state.count) // 1
    }, 0)
 }

  render() {
    return (
      <div>
        {`Count is: ${this.state.count}`}
      </div>
    )
  }
}

总结

  • setTimeout和原生事件都会直接去更新state,因此可以立即得到最新state。
  • 合成事件和React生命周期函数中,受React控制的,其会将isBatchingUpdates设置为 true,从而走“异步”行为。
  • setState更新状态时可能会导致页面不必要的重新渲染,影响加载。
  • setState管理大量组件状态也许会导致不必要的生命周期函数钩子调用。

参考链接:https://juejin.im/post/5bf1444cf265da614a3a1660

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逸尘️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值