简体   繁体   English

由于firebase我的React应用程序中的内存泄漏以及如何避免它?

[英]Memory leak in my React app because of firebase and how to avoid it?

The app I'm working on displays a user dashboard on login with a sidebar for navigation. 我正在使用的应用程序在登录时显示用户仪表板,并带有用于导航的侧栏。 It uses firebase. 它使用firebase。 I do most of my data fetch from firebase in my async componentDidMount() and store the data in my component state. 我在async componentDidMount()从firebase获取大部分数据,并将数据存储在组件状态中。 It takes a couple of seconds to finish all fetches. 完成所有提取需要几秒钟。 But if the user decides to navigate to another screen before the fetch is complete, I get the 但是如果用户在获取完成之前决定导航到另一个屏幕,我就会得到

Can't call setState on unmounted component 无法在未安装的组件上调用setState

warning (as expected). 警告(如预期的那样)。 So I do some digging and find that 所以我做了一些挖掘并找到了

if(this.isMounted()) this.setState({updates:updates})

makes the warning go away, but then I also find that using isMounted is an antipattern. 使警告消失,但后来我也发现使用isMounted是一个反模式。

The official documentation on this issue suggests tracking the mounted state ourselves by setting _isMounted=true in componentDidMount and then set it to false in the componentWillUnmount . 在这个问题上的官方文档建议通过设置跟踪安装状态下自己_isMounted=truecomponentDidMount ,然后将其设置为假componentWillUnmount The only way I see to achieve this would be through a variable in component state. 我看到实现这一目标的唯一方法是通过组件状态中的变量。 Turns out, setState doesn't work in componentWillUnmount. 事实证明,setState在componentWillUnmount中不起作用。 [Issue 1] (I tried calling an external function from componentWillUnmount which in turn sets the state variable. Didn't work.) [问题1] (我尝试从componentWillUnmount调用外部函数,然后设置状态变量。没有用。)

The documentation suggests another way, to use cancellable promises. 文档提出了另一种方法,即使用可取消的承诺。 But I'm clueless about how to achieve that with await firebase calls. 但我对如何通过await firebase调用实现这一点毫无头绪。 I also couldn't find any way to stop firebase calls mid-track. 我也找不到任何方法来阻止firebase中途跟踪。 [Issue 2] [问题2]

So now I'm stuck with the warning and data leaks. 所以现在我坚持警告和数据泄漏。

a. 一个。 How do I resolve this problem? 我该如何解决这个问题?
b. Is this something I need to take seriously? 这是我需要认真对待的事吗?

It's good practice to check if the component is still mounted when a request completes, if there is a risk of the component unmounting. 如果存在组件卸载的风险,最好在请求完成时检查组件是否仍处于挂载状态。

You don't need to put _isMounted in your component state since it will not be used for rendering. 您不需要将_isMounted放在组件状态中,因为它不会用于渲染。 You can put it directly on the component instance instead. 您可以将其直接放在组件实例上。

Example

class MyComponent extends React.Component {
  state = { data: [] };

  componentDidMount() {
    this._isMounted = true;

    fetch("/example")
      .then(res => res.json())
      .then(res => {
        if (this._isMounted) {
          this.setState({ data: res.data });
        }
      });
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  render() {
    // ...
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM