React中两个setState调用次数是多少,调用是哪个
Admin 2022-07-06 群英技术资讯 640 次浏览
如下代码所示,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
的值进行加1
,render()
应该会执行两次,最后count
的值应该是2。但是 React 并不是这么执行的。
以上代码放到浏览器运行一下即可:
最开始时,页面显示count
的值为0
,控制台打印出render
,这是 React 首次渲染时打印的。当点击完按钮后,页面显示count
值是1
,同时也只打印了1
个render
,说明在这过程中 React 只执行了一次setState
,只执行了一次render()
渲染操作。
原因在于,React 内部将同一事件响应函数中的多个setState
进行合并,减少setState
的调用次数,也就能减少渲染的次数,提高性能。
这也就解释了上述代码,为什么最后count
的值是1
,因为 React 将两个setState
进行了合并,最终只执行了1
次,render()
也只执行了一次。
但上述代码没有验证,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
中的属性。
若在点击事件函数中,添加一个定时器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
。
在 React 中直接使用的事件,如onChange
、onClick
等,都是由 React 封装后的事件,是合成事件,由 React 管理。
React 对于合成事件和生命周期函数,有一套性能优化机制,会合并多个setState
,若出现同名属性,会将后面的同名属性覆盖掉前面的同名属性。
若越过 React 的性能优化机制,在原生事件、setTimeout
中使用setState
,就不归 React 管理了,写了几次setState
,就会调用几次setState
。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
嵌套路由顾名思义就是路由的多层嵌套,这篇文章主要给大家介绍了关于Vue实现路由嵌套的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
JS实现表单验证案例 本文实例为大家分享了JS实现表单验证案例的具体代码,供大家参考,具体内容如下 1.当输入框失去焦点时,验证输入内容是否符合要求 (1)获取表单输入框(2)绑定 onblur 事件(3)获取输入内容(4)判断是否符合规则(5)如果不符合规则,则显示错误提示信息 2.当点击注册按钮是,判断所有输入框的内容是否符合要求,如果不符合则阻止表单提交 (1)获取表单对象(2)微表单对象绑定 onsubmit(3)判断所有输入框是否都符合要求,如果符合,则返回true,如果有一项不符合,则返回false &l ...
这篇文章主要为大家介绍了JSON Schema概念及使用场景示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
gm是基于node.js的图片处理插件,它封装了图片处理工具GraphicsMagick(GM)和ImageMagick(IM),可使用spawn的方式调用。gm插件不是node默认安装的,需执行“npm install gm -S”进行安装才可使用。
这篇文章主要介绍了如何理解JavaScript中的数据类型,帮助大家更好的学习JavaScript,感兴趣的朋友可以了解下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008