[英]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=true
在componentDidMount
,然后将其设置为假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.