【问题标题】:async inside useEffect react异步内部 useEffect 反应
【发布时间】:2021-05-30 18:03:47
【问题描述】:

所以我有一个运行异步的函数,所以把异步放在useEffect里面,下面是我的代码

 useEffect(() => {
    const data = async () => {
      const data = await getAllVertification();
      if (!data.status) {
      } else {
        setAlldata(data.data);
        setLoadingAction([]);
        let tmp = [];
        for (const element of data.data) {
          tmp.push({ status: false });
        }
        setLoadingAction(tmp);
      }
    };

    data();
  }, [update]);

但像这样逐渐减弱

React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. 
To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

谁能给我解释一下?

【问题讨论】:

标签: reactjs next.js


【解决方案1】:

在卸载组件时,您需要在await 解析后取消操作。这是执行此操作的方法之一。

  useEffect(() => {
    let isSubscribed = true;
    const data = async () => {
      const data = await getAllVertification();
      if(isSubscribed) {
        if (!data.status) {
        } else {
          setAlldata(data.data);
          setLoadingAction([]);
          let tmp = [];
          for (const element of data.data) {
            tmp.push({ status: false });
          }
          setLoadingAction(tmp);
        }
      }
    };
    data();
    return () => (isSubscribed = false);
  }, [update]);

【讨论】:

    【解决方案2】:

    重写代码以使其更清晰:

     useEffect(() => {
        const getData = async () => {
          const data = await getAllVertification();
          if (!data.status) {
          } else {
            setAlldata(data.data);
            setLoadingAction([]);
            let tmp = [];
            for (const element of data.data) {
              tmp.push({ status: false });
            }
            setLoadingAction(tmp);
          }
        };
    
        getData();
      }, [update]);
    

    这里的getData 是一个异步函数,这意味着当您运行它时,它会返回一个承诺,该承诺将在当前事件循环周期结束时执行。 不过,您不必制作getData
    试试这个:

     useEffect(() => {
        getAllVertification().then(data => {
          if (!data.status) {
          } else {
            setAlldata(data.data);
            setLoadingAction([]);
            let tmp = [];
            for (const element of data.data) {
              tmp.push({ status: false });
            }
            setLoadingAction(tmp);
          }
        }
      }, [update]);
    

    【讨论】:

      【解决方案3】:

      使用自定义钩子,我们可以做到以下几点:

      import { useAsyncEffect } from "use-async-effect2";
      
      // ...
      
       useAsyncEffect(function*(){
            const data = yield getAllVertification();
            if (data.status) {
              setAlldata(data.data);
              let tmp = [];
              for (const element of data.data) { 
                tmp.push({ status: false }); // weird code
              }
              setLoadingAction(tmp);
            }
          };
        }, [update]);
      

      【讨论】:

        猜你喜欢
        • 2020-12-03
        • 2023-01-30
        • 2023-03-31
        • 2019-11-22
        • 2016-12-26
        • 1970-01-01
        • 2018-04-06
        • 2020-07-08
        • 2020-09-27
        相关资源
        最近更新 更多