解决react中useState状态异步更新的问题.docxVIP

解决react中useState状态异步更新的问题.docx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

解决react中useState状态异步更新的问题

目录疑惑状态异步更新带来的问题问题示例问题解决类组件的解决方案函数组件的解决方案其他解决方案结尾

疑惑

相信刚开始使用react函数组件的小伙伴也遇到过一个坑,就是useState更新状态是异步更新的,但是react并没有提供关于这个问题的解决方案。那我们能否使用自己的方法来解决这个问题呢?答案肯定是可以的。

状态异步更新带来的问题

就拿一个比较常见的场景来说。在react项目中,我们想在关闭对话框后再去处理其他业务。但是useState的状态是异步更新的。我们通过setVisible更新状态后,状态并没有立马更新,这也就说明对话框并没有关闭,这也就造成了我们后面的逻辑在对话框没关闭时就执行了,这并不是我们想要的结果。下面来看我是如何来巧妙的解决这个问题的。

问题示例

//App.tsx

import{useState}fromreact

exportdefault()={

const[num,setNum]=useState(0)

constadd=()={

console.log(更新前,num)

setNum(num+1)

console.log(更新后,num)

return(

divclassName=App

p{num}/p

buttonadd}num++/button

/div

下面是上面组件运行结果:

点击按钮后的运行结果:

当我们点击按钮时的打印结果:

问题解决

类组件的解决方案

在类组件中,我们可以在setState(newstate,callback)第二个参数传一个回调来处理本次状态更新后的一些其他业务。但是在函数组件中我们如何来解决这个问题呢?来看以下方案,也是我们这篇文章主要想为大家解决的问题。

函数组件的解决方案

解决该问题使用到的api有:useEffect,Promise

1.在项目源码目录下创建文件夹customHooks,然后在customHooks/useCallbackState.ts中编写如下代码:

import{useState,useRef,useEffect}fromreact;

exportdefault(initState:any)={

conststateRef=useRef(nullasany);

const[state,setState]=useState(initState);

useEffect(()={

stateRef.currentstateRef.current(state);

},[state]);

return[

state,

(newState:typeofinitState):PromisetypeofinitState=

newPromise(rel={stateRef.current=rel;setState(newState)})

2.在上面的App.tsx中使用上面的自定义hook

importuseCallbackStatefrom@/customHooks/useCallbackState

const[num,setNum]=useCallbackState(0)

constadd=()={

console.log(更新前,num)

setNum(num+1)

.then((newNum:any)={

console.log(更新后,newNum)

//console.log(num)

此时的运行结果如下:

注意:谨慎使用,打印可以看出,其实状态并没有真正完成更新。依然达不到类组件callback的效果。

其他解决方案

如果真的存在上面这种需求,我们可以使用类组件,或者使用setTimeout来解决上面的问题,把对话框关闭后的业务写在延时的回调中就行了,延时个500毫秒状态一定更新完毕了,个人感觉这个方法不太好,还是推荐使用类组件来解决上述问题。

结尾

文档评论(0)

132****1508 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档