setstate 问题求助大佬

2022-11-08 20:57:00 +08:00
 panghu1

页面 组件 1(表格 组件内 axios 请求数据) 组件 2(表格 组件内 axios 请求数据) 组件 3(表格 组件内 axios 请求数据) 组件 4(表格 组件内 axios 请求数据) 组件 5(表格 组件内 axios 请求数据) 页面里面有 5 个 组件,全部都是请求不同接口返回的数据

async getData(){
	console.log("1")
    var data=await getApi()
    console.log("2")
    this.setState({
        loading:false,
        list:data.data
    },()=>{console.log("ok")}
	)
    
    console.log("3")

}

偶发性 某个组件 setState 没反应 不会打印 ok ,会打印 1 ,2 ,3,手动执行一次 getData() 会打印 2 次 ok ,1 次 1,2,3 之后正常。

这个问题找了我一天,f5 按烂了 因为是偶发的 很难判断是什么地方出了问题,只能不断注掉代码,但是找了一天还是一头雾水,有没有懂哥给点思路

现在摸索到的就是偶发性 setState 不执行,下次执行 setState 的时候会把上一次没执行的也执行一次(因为 callback 里的 log 会打印 2 次)

1961 次点击
所在节点    React
9 条回复
weiwoxinyou
2022-11-08 21:03:35 +08:00
偶发性的时候是不是因为 setState 是异步更新导致 pending
panghu1
2022-11-08 21:09:57 +08:00
@weiwoxinyou 异步最终还是会执行呀,但是它一直不执行。只有等你自己手动在调一个 setstate 才会让上次的队列里的消息执行
panghu1
2022-11-08 21:10:40 +08:00
不知道是不是错觉,我把 table 的骨架加载去掉后发生的几率变低了,但还是会发生
panghu1
2022-11-08 22:05:48 +08:00
下一次 setstate 的时候会有 2 个 callback 一个是本次的 一个是上次的
kidlj
2022-11-08 22:11:15 +08:00
浏览器有一个 limit number ,限制同一时间对同一 server 的连接数量,Chrome 里这个值是 6 ,Firefox 是 15.

ref: https://stackoverflow.com/questions/8404464/increasing-google-chromes-max-connections-per-server-limit-to-more-than-6

不知道跟这个有没有关系,你可以试着减少并发请求的数量或者换到 Firefox 试一试。
ragnaroks
2022-11-08 22:20:03 +08:00
setState 执行之后的效果是压入一个更新队列,而不是立刻执行你预期的动作,react 自己会根据优先级处理。而且 react 和异步有点不协调,最好还是使用函数组件和 hooks ,用返回值的形式封装 fetch 调用。
ragnaroks
2022-11-08 22:24:10 +08:00
你一定要用你的做法的话,可以尝试

async getData(){
 const update = async function(){
  this.setState({loading:false,list:data.data},function(){console.log("ok");}});
 };
 console.log("1");
 const data = await getApi();
 console.log("2");
 await update();
 console.log("3");
}
Angela2022
2022-11-09 01:58:39 +08:00
1. setstate 是异步的, 要等到下个批次执行, 拖上几分钟后执行很正常.
2. setstate 中的 state 数据如果没有变化时 setstate callack 不会被执行
panghu1
2022-11-09 09:08:11 +08:00
@ragnaroks 改成了函数组建了 谢谢
@kidlj 谢谢不是这个问题,接口数据都返回了。
@Angela2022 谢谢,数据是有变化的,不然就是每次都不变化了,而不是偶发

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/893684

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX