React setState的用法是怎样的,有何用处
Admin 2022-10-21 群英技术资讯 741 次浏览
这篇文章给大家分享的是React setState的用法是怎样的,有何用处。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。在React 的开发过程中,难免会与组件的state打交道。使用过React 的都知道,想要修改state中的值,必须使用内部提供的setState 方法。为什么不能直接使用赋值的方式修改state的值呢?我们就分析一下,先看一个demo。
?class Index extends React.Component { this .state = { count: 0 } onClick = () => { this .setState({ count: 10 }) } render() { return ( <div> <span>{ this .state.count}</span> <button onClick={ this .onClick}>click</button> </div> ) } } |
根据上面代码可以看到,点击按钮后把state 中 count 的值修改为 10。并更新页面的显示。所以state的改变有两个作用:对应的值改变 和 **页面更新。**要想做到这两点在react 中 非 setState 不可。 假如说我们把 onClick 的方法内容修改为 this.state.count = 10 并在方法内打印出 this.state 的值,可以看到state的值已经改变。但是页面并没有更新到最新的值。 总结一下:
扩展一下:
在vue中,采用的就是直接赋值的方式来更新data 数据,并且Vue也能够使用最新的data数据渲染页面。这是为什么呢? 在vue2中采用的是 Object.defineProperty() 方式监听数据的get 和 set 方法,做到数据变化的监听 在vue3中采用的是ES6 的 proxy 方式监听数据的变化
想必所有人都会知道setState 的用法,在这里还是想记录一下: setState方法有两个参数:第一个参数可以是对象直接修改属性值,也可以是函数能够拿到上一次的state值。第二个参数是一个可选的回调函数,可以获取最新的state值 回调函数会在组件更新完成之后执行,等价于在 componentDidUpdate 生命周期内执行。
this .setState({ key:newState }) |
// prevState 是上一次的 state,props 是此次更新被应用时的 props this .setState((prevState, props) => { return { key: prevState.key } }) |
setState() 将对组件 state 的更改排入队列,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式 将 setState() 视为请求而不是立即更新组件的命令。为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。
先修改一下上面的代码,如果在onClick 方法中连续调用三次setState,根据上文可知 setState是一个异步的方式,每次调用只是将更改加入队列,同步调用的时候只会执行最后一次更新,所以结果是1而不是3。
?onClick = () => { const { count } = this .state this .setState({ count: count + 1 }) this .setState({ count: count + 1 }) this .setState({ count: count + 1 }) } |
可以把上面代码理解为 Object.assign() 方法,
Object.assign( state, { count: state.count + 1 }, { count: state.count + 1 }, { count: state.count + 1 } ) |
如果第一个参数传入一个函数,连续调用三次,是不是和传入对象方式的结果是一样的呢?
?onClick = () => { this .setState((prevState, props) => { return { count: prevState.count + 1 } }) this .setState((prevState, props) => { return { count: prevState.count + 1 } }) this .setState((prevState, props) => { return { count: prevState.count + 1 } }) } |
结果和传入对象的方式大相径庭,使用函数的方式就能够实现自增为3的效果。这又是为什么呢? 在函数内能够拿到最新的state 和 props值。由上文可知 setState 的更新是分批次的,使用函数的方式确保了当前state 是建立在上一个state 之上的,所以实现了自增3的效果。
总结一下: 为什么setState 方法是异步的呢?
**是不是所有的setState 都是异步的形式呢?**答案是 否!!!在React 中也会存在setState 同步的场景
?onClick = () => { this .setState({ count: this .state.count + 1 }) console.log( this .state) setTimeout(() => { this .setState({ count: this .state.count + 1 }) console.log( this .state) }, 0) } |
上面的代码会打印出**0,2。**这又是为什么呢?其实React 中的 setState 并不是严格意义上的异步函数。他是通过队列的延迟执行实现的。使用 isBatchingUpdates 判断当前的setState 是加入到更新队列还是更新页面。当 isBatchingUpdates=ture 是加入更新队列,否则执行更新。
知道了React 是使用 isBatchingUpdates 来判断是否加入更新队列。那么为什么在 setTimeout 事件中 isBatchingUpdates 值为 false ? 原因就是在React中,对HTML的原生事件做了一次封装叫做**合成事件。**所以在React自己的生命周期和合成事件中,可以控制 isBatchingUdates 的值,可以根据值来判断是否更新页面。而在宿主环境提供的原生事件中(即非合成事件),无法将 isBatchingUpdates 的值置为 false,所以就会立即执行更新。
所以setState 并不是有同步的场景,而是在特殊的场景下不受React 的控制 **
setState 并不是单纯的同步函数或者异步函数,他的同步和异步的表现差异体现在调用的场景不同。在React 的生命周期和合成事件中他表现为异步函数。而在DOM的原生事件等非合成事件中表现为同步函数。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)
排序算法是笔试中经常出现的,提起排序算法就一定要提下算法复杂度和大O表示法,算法复杂度是指算法在编写成可执行程序后,运行时所需要的资源,资源包括时间资源和内存资源,这篇文章主要给大家介绍了关于如何利用JavaScript实现排序算法的相关资料,需要的朋友可以参考下
这篇文章我们来了解TypeScript的函数重载功能的相关内容,主要介绍TypeScript中函数重载写法,下文有很详细的介绍,对大家学习或工作会有帮助,接下来就跟随小编来一起学习一下吧!
微信小程序canvas实现环形渐变 本文实例为大家分享了微信小程序canvas实现环形渐变的具体代码,供大家参考,具体内容如下 这个例子是在微信小程序中写的 效果图 后端返回的数据格式,需要的只有otherInfo里面的数据 wxml <view> <canvas class="progress_bg" canvas-id="{{otherInfo.bgid}}"> </canvas> <canvas class="prog ...
本文实例为大家分享了微信小程序实现轮播图指示器的具体代码,供大家参考,具体内容如下1.文件目录2.轮播图页面布局需求:自定义轮播指示器:当轮播图发生变化时,自定义轮播指示器跟随图片发生对应改变bindchange:current 改变时会触发 change 事件,即当图片索引发生变化时触发的事件current:当前所在
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008