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

前端小白 求助 react 问题

  •  
  •   hua123s ·
    powerfulyang · 2019-10-22 12:00:21 +08:00 · 3292 次点击
    这是一个创建于 1859 天前的主题,其中的信息可能已经有所发展或是发生改变。

    萌新用 react hooks 写了个组件

    const [status,setStatus]=useState(false);
    useEffect(() => {
        (async () => {
            await init();
         })();
    }, [domain]);
    

    init()方法

    const init = async () => {
        request().then(res=>{setStatus(true)}); //request 很慢慢
      };
    

    现在出现当我外部改变 props domain的时候 init 方法还没执行完 最后导致 state 值先被第二次 reqeust 设置 然后又被第一次 request 改变了 state 的值

    求助 我改如何避免第一次请求晚于第二次改变 state ? 或者有什么别的方法?

    10 条回复    2020-02-08 23:54:29 +08:00
    zizhoutong
        1
    zizhoutong  
       2019-10-22 12:40:11 +08:00
    我也是萌新,但有个疑问。既然第一次渲染组件 init 没有执行完,改变 domain 第二次调用 init,那也应该是第一次先返回 res 对吗?
    seki
        2
    seki  
       2019-10-22 12:49:35 +08:00   ❤️ 1
    async () => { await init() } 这一句没什么含义,直接写 init 就好

    取决于你的设计要求,可以
    1. 实现一个简单的 promise 队列,保证第一个 promise resolve 之后开第二个请求
    2. 用 p-cancelable 之类的库,在 domain 改变之后先 cancel 之前的 promise,再开新的 promise
    xiaojiqiaozhi
        3
    xiaojiqiaozhi  
       2019-10-22 13:30:43 +08:00 via Android
    把 domain 传给 init 作为参数 d,请求完成后判断如果 d 和 domain 相等,setState,否则不做任何操作
    hua123s
        4
    hua123s  
    OP
       2019-10-22 14:09:47 +08:00
    @xiaojiqiaozhi 我试了试,d 和 domain 一直都是相等的。。。。好奇怪
    hua123s
        5
    hua123s  
    OP
       2019-10-22 14:11:00 +08:00
    @zizhoutong 这个倒不是,第二个请求可能更快
    hua123s
        6
    hua123s  
    OP
       2019-10-22 14:13:22 +08:00
    @seki 2 是我想要的需求 :smile:
    wyatt1e34
        7
    wyatt1e34  
       2019-10-22 15:44:56 +08:00   ❤️ 1
    ```javascript

    const [status,setStatus]=useState(false);
    useEffect(() => {
    let isCancel = false;
    const init = () => {
    request().then(res=>{
    if (isCancel) {
    return;
    } else {
    setStatus(true);
    }
    }); //request 很慢慢
    };
    init();
    return () => { isCancel = true }

    }, [domain]);

    ```

    加一个 isCancel 标识符就可以
    Philippa
        8
    Philippa  
       2019-10-22 18:28:15 +08:00 via iPhone
    😨 async await then useEffect 混到一起,我看懂你的代码但完全看不懂你写什么
    hua123s
        9
    hua123s  
    OP
       2019-10-22 21:58:30 +08:00 via iPhone
    @wyatt1e34 是的~一开始的时候把 flag 用 useState 定义的,setState 好乱啊,一个组件的 props 是独立的,但是 state 是公用的好晕
    googleGirl
        10
    googleGirl  
       2020-02-08 23:54:29 +08:00 via iPhone
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2422 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:59 · PVG 23:59 · LAX 07:59 · JFK 10:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.