V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
panghu1
V2EX  ›  React

setstate 问题求助大佬

  •  
  •   panghu1 · 2022-11-08 20:57:00 +08:00 · 1933 次点击
    这是一个创建于 747 天前的主题,其中的信息可能已经有所发展或是发生改变。

    页面 组件 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 次)

    9 条回复    2022-11-09 09:08:11 +08:00
    weiwoxinyou
        1
    weiwoxinyou  
       2022-11-08 21:03:35 +08:00
    偶发性的时候是不是因为 setState 是异步更新导致 pending
    panghu1
        2
    panghu1  
    OP
       2022-11-08 21:09:57 +08:00
    @weiwoxinyou 异步最终还是会执行呀,但是它一直不执行。只有等你自己手动在调一个 setstate 才会让上次的队列里的消息执行
    panghu1
        3
    panghu1  
    OP
       2022-11-08 21:10:40 +08:00
    不知道是不是错觉,我把 table 的骨架加载去掉后发生的几率变低了,但还是会发生
    panghu1
        4
    panghu1  
    OP
       2022-11-08 22:05:48 +08:00
    下一次 setstate 的时候会有 2 个 callback 一个是本次的 一个是上次的
    kidlj
        5
    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
        6
    ragnaroks  
       2022-11-08 22:20:03 +08:00
    setState 执行之后的效果是压入一个更新队列,而不是立刻执行你预期的动作,react 自己会根据优先级处理。而且 react 和异步有点不协调,最好还是使用函数组件和 hooks ,用返回值的形式封装 fetch 调用。
    ragnaroks
        7
    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
        8
    Angela2022  
       2022-11-09 01:58:39 +08:00
    1. setstate 是异步的, 要等到下个批次执行, 拖上几分钟后执行很正常.
    2. setstate 中的 state 数据如果没有变化时 setstate callack 不会被执行
    panghu1
        9
    panghu1  
    OP
       2022-11-09 09:08:11 +08:00
    @ragnaroks 改成了函数组建了 谢谢
    @kidlj 谢谢不是这个问题,接口数据都返回了。
    @Angela2022 谢谢,数据是有变化的,不然就是每次都不变化了,而不是偶发
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2868 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:55 · PVG 22:55 · LAX 06:55 · JFK 09:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.