【问题标题】:How to get rid of memory leak in react web app如何摆脱 React Web 应用程序中的内存泄漏
【发布时间】:2020-04-09 18:17:34
【问题描述】:

我的 ReactJS Web 应用程序中有这段代码:

useEffect(() => {
    const fetchInfo = async () => {
      const res = await fetch(`${api}&page=${page}`);
      setLoading(true);
      try {
        const x = await res.json();
        if (page === 1) {
          setItems(x);
          setAutoplay(true);
        } else {
          setItems({
            hasMore: x.hasMore,
            vacancies: [...items.vacancies, ...x.vacancies],
          });
        }
      } catch (err){
        console.log(err);
      }
      setLoading(false);
    };
    fetchInfo();
  }, [page]);

当这个组件在运行异步函数时卸载时,它会在控制台中抛出一个错误。

Warning: Can't perform a 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.

如何在清理中取消异步任务。

【问题讨论】:

    标签: javascript reactjs memory-leaks


    【解决方案1】:

    我在这里假设setLoading 是在组件卸载后设置状态的函数,因此会抛出此警告。如果是,那么您需要的是清理功能。

    传递给useEffect 的函数可以返回一个函数,该函数将在组件卸载之前被调用(你可以认为它相当于旧的componentWillUnmount)- 更多细节在这里:

    https://reactjs.org/docs/hooks-effect.html#example-using-hooks

    现在您可能想要的是某种标志来检查您调用setLoading 是否安全,即默认将该标志设置为true,然后在返回时将其设置为false功能。这是一篇应该有所帮助的好文章:

    https://juliangaramendy.dev/use-promise-subscription/

    现在我还没有对此进行测试,但基本上你的代码看起来像这样:

    useEffect(() => {
        const fetchInfo = async () => {
            let isSubscribed = true;
            const res = await fetch(`${api}&page=${page}`);
            if (isSubscribed) setLoading(true);
            try {
                const x = await res.json();
                if (page === 1) {
                    setItems(x);
                    setAutoplay(true);
                } else {
                    setItems({
                        hasMore: x.hasMore,
                        vacancies: [...items.vacancies, ...x.vacancies]
                    });
                }
            } catch (err) {
                console.log(err);
            }
            if (isSubscribed) setLoading(false);
    
            return () => (isSubscribed = false);
        };
        fetchInfo();
    }, [page]);
    

    【讨论】:

      猜你喜欢
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 2022-07-30
      • 2020-09-22
      • 2011-02-18
      • 1970-01-01
      • 2012-11-09
      • 1970-01-01
      相关资源
      最近更新 更多