我的React应用由于Firebase而导致内存泄漏,如何避免?

时间:2018-07-08 20:32:26

标签: javascript reactjs firebase

我正在使用的应用在登录时会显示一个用户仪表板,并带有用于导航的侧边栏。它使用firebase。我在async componentDidMount()中从firebase提取了大部分数据,并将数据存储在组件状态下。完成所有提取需要花费几秒钟的时间。但是,如果用户决定在提取完成之前导航到另一个屏幕,我会得到

  

无法在未安装的组件上调用setState

警告(如预期)。因此,我进行了一些挖掘并找到了

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

使警告消失,但随后我还发现使用isMounted是一种反模式。

有关此问题的官方文档建议通过在_isMounted=true中设置componentDidMount并在componentWillUnmount中将其设置为false来自己跟踪安装状态。我看到实现此目标的唯一方法是通过组件状态下的变量。事实证明,setState在componentWillUnmount中不起作用。 [问题1] (我尝试从componentWillUnmount调用外部函数,该函数依次设置状态变量。不起作用。)

文档提出了使用可撤销承诺的另一种方法。但是我对如何通过await firebase调用来实现这一点一无所知。我也找不到任何方法来阻止火力发来的中途呼叫。 [问题2]

所以现在我被警告和数据泄漏所困扰。

a。如何解决此问题?
b。这是我需要认真对待的事情吗?

1 个答案:

答案 0 :(得分:3)

优良作法是在请求完成后检查组件是否仍在安装中,是否存在卸载组件的风险。

您无需将_isMounted置于组件状态,因为它不会用于呈现。您可以直接将其放在组件实例上。

示例

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() {
    // ...
  }
}