浅谈React多个setState会调用几次

 更新时间:2021年11月12日 09:57:52   作者:火星飞鸟  
在React的生命周期钩子和合成事件中,多次执行setState,会被调用几次,本文就详细的介绍一下,感兴趣的可以了解一下

1. 两个setState,调用几次?

如下代码所示,state中有一个count。对按钮绑定了点击事件,事件中执行了两次setState,每次都将count的值加1

当点击按钮时,setState会执行几次?render()会执行几次?

答案:都是1次。

state = { count: 0 };
handleClick = () => {
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
};
render() {
    console.log(`render`);
    return (
        <>
            <div>当前计数:{this.state.count}</div>
            <button onClick={this.handleClick}>add</button>
        </>
    );
}

按照常理来说,第一次点击按钮时,由于执行了两次两次setState,每次都将count的值进行加1render()应该会执行两次,最后count的值应该是2。但是 React 并不是这么执行的。

以上代码放到浏览器运行一下即可:

最开始时,页面显示count的值为0,控制台打印出render,这是 React 首次渲染时打印的。当点击完按钮后,页面显示count值是1,同时也只打印了1render,说明在这过程中 React 只执行了一次setState,只执行了一次render()渲染操作。

原因在于,React 内部将同一事件响应函数中的多个setState进行合并,减少setState的调用次数,也就能减少渲染的次数,提高性能。

这也就解释了上述代码,为什么最后count的值是1,因为 React 将两个setState进行了合并,最终只执行了1次,render()也只执行了一次。

2. 两个setState,调用的是哪一个?

但上述代码没有验证,React 合并后,到底执行的是哪一次setState。如下代码所示,将第二个setState中,对count的操作改为加2,其余代码保持不变:

state = { count: 0 };
handleClick = () => {
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 2 }); // 改为+2
};
render() {
    console.log(`render`);
    return (
        <>
            <div>当前计数:{this.state.count}</div>
            <button onClick={this.handleClick}>add</button>
        </>
    );
}

再次放到浏览器中执行:

结果显示,点击按钮后,count的值最终变成了2,也就是进行了+2的操作,render()也只执行了1次。这就说明 React 在合并多个setState时,若出现同名属性,会将后面的同名属性覆盖掉前面的同名属性。可以这么理解,对于同名属性,最终执行的的是最后setState中的属性。

3. 两个setState放在setTimeout中?

若在点击事件函数中,添加一个定时器setTimeout,在定时器中执行两次setState操作,结果又将如何?如下代码,事件处理函数中,写了一个定时器setTimeout,将两次setState放入setTimeout中。

state = { count: 0 };
handleClick = () => {
    setTimeout(() => {
        this.setState({ count: this.state.count + 1 });
        this.setState({ count: this.state.count + 2 });
    }, 0);
};
render() {
    console.log(`render`);
    return (
        <>
            <div>当前计数:{this.state.count}</div>
            <button onClick={this.handleClick}>add</button>
        </>
    );
}

运行结果:

结果显示,点击按钮后,count的值最终变成了3,也就+1+2的操作都执行了,render()也执行了2次。

这是因为在 React 的合成事件生命周期函数中直接调用setState,会交由 React 的性能优化机制管理,合并多个setState。而在原生事件setTimeout中调用setState,是不受 React 管理的,故并不会合并多个setState,写了几次setState,就会调用几次setState

4. 总结

在 React 中直接使用的事件,如onChangeonClick等,都是由 React 封装后的事件,是合成事件,由 React 管理。

React 对于合成事件和生命周期函数,有一套性能优化机制,会合并多个setState,若出现同名属性,会将后面的同名属性覆盖掉前面的同名属性

若越过 React 的性能优化机制,在原生事件setTimeout中使用setState,就不归 React 管理了,写了几次setState,就会调用几次setState

到此这篇关于浅谈React多个setState会调用几次的文章就介绍到这了,更多相关浅谈React多个setState会调用几次内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于antd的autocomplete的二次封装查询示例

    基于antd的autocomplete的二次封装查询示例

    这篇文章主要为大家介绍了基于antd的autocomplete的二次封装查询示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • react-native弹窗封装的方法

    react-native弹窗封装的方法

    这篇文章主要为大家详细介绍了react-native弹窗封装的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • React路由鉴权的实现方法

    React路由鉴权的实现方法

    这篇文章主要介绍了React路由鉴权的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 无废话快速上手React路由开发

    无废话快速上手React路由开发

    本文以简洁为目标,帮助快速上手react-router-dom默认你接触过路由相关的开发,通过实例代码讲解的很详细,对React路由相关知识感兴趣的朋友一起看看吧
    2021-05-05
  • 解决React初始化加载组件会渲染两次的问题

    解决React初始化加载组件会渲染两次的问题

    这篇文章主要介绍了解决React初始化加载组件会渲染两次的问题,文中有出现这种现象的原因及解决方法,感兴趣的同学跟着小编一起来看看吧
    2023-08-08
  • 详解react使用react-bootstrap当轮子造车

    详解react使用react-bootstrap当轮子造车

    本篇文章主要介绍了详解react使用react-bootstrap当轮子造车,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-08-08
  • react 父子组件之间通讯props

    react 父子组件之间通讯props

    这篇文章主要介绍了react 父子组件之间通讯props,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • React实现简单登录的项目实践

    React实现简单登录的项目实践

    登录、注册、找回密码是前端项目经常遇到的需求,本文主要介绍了React实现简单登录的项目实践,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • react中hooks使用useState的更新不触发dom更新问题及解决

    react中hooks使用useState的更新不触发dom更新问题及解决

    这篇文章主要介绍了react中hooks使用useState的更新不触发dom更新问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • react+redux的升级版todoList的实现

    react+redux的升级版todoList的实现

    本篇文章主要介绍了react+redux的升级版todoList的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12

最新评论