这是一个常见问题,但我知道为什么,并且通常可以很快解决。
但是,在这种情况下,我似乎无法卸载我的ReactJS和GatsbyJS应用程序中的任务。
下面的代码正在监听Firebase auth
的变化,并且setState
与auth
的用户详细信息在state
中可用
_initFirebase = false;
constructor(props) {
super(props);
this.state = {
authUser: null
};
}
firebaseInit = () => {
const { firebase } = this.props;
if (firebase && !this._initFirebase) {
this._initFirebase = true;
this.listener = firebase.onAuthUserListener(
authUser => {
localStorage.setItem('authUser', JSON.stringify(authUser));
this.setState({ authUser });
},
() => {
localStorage.removeItem('authUser');
this.setState({ authUser: null });
}
);
}
};
componentDidMount() {
this.setState({
authUser: JSON.parse(localStorage.getItem('authUser'))
});
this.firebaseInit();
}
componentDidUpdate() {
this.firebaseInit();
}
componentWillUnmount() {
this.listener && this.listener();
}
在控制台中引起错误
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 the componentWillUnmount method.
in WithAuthentication (created by Context.Consumer)
in Component (created by Layout)
in Layout (created by SigninPage)
in SigninPage (created by HotExportedSigninPage)
in AppContainer (created by HotExportedSigninPage)
in HotExportedSigninPage (created by PageRenderer)
据我了解,我在unmount
内已经足够setState
个componentWillUnmount
任务。
您能解释一下我可能错过的事情吗?
答案 0 :(得分:1)
问题是您正在尝试在componentWillUnmount触发后设置setState ... 您无法在componentWillUnmount中设置setState。
您的用例解决方案:
initFirebase = false;
constructor(props) {
super(props);
this.state = {
authUser: null
};
// this prop to check component is live or not
this.isAmAlive = false;
}
firebaseInit = () => {
const { firebase } = this.props;
if (firebase && !this._initFirebase) {
this._initFirebase = true;
this.listener = firebase.onAuthUserListener(
authUser => {
localStorage.setItem('authUser', JSON.stringify(authUser));
//check component is live or not if live update the component
if(this.isAmAlive){
this.setState({ authUser });
}
},
() => {
localStorage.removeItem('authUser');
//check component is live or not if live update the component
if(this.isAmAlive){
this.setState({ authUser : null });
}
}
);
}
};
componentDidMount() {
this.isAmAlive =true;
this.setState({
authUser: JSON.parse(localStorage.getItem('authUser'))
});
this.firebaseInit();
}
componentDidUpdate() {
this.firebaseInit();
}
componentWillUnmount() {
this.isAmAlive = false;
this.listener && this.listener();
}