I am currently changing my app files from class with lifecycle events such as componentDidMount to functions with useEffect hooks.
For most files I haven't seen any issues but on the below, I am getting a performance issue, where the app freezes. Zero errors or warnings in the console but my machine and Chrome increases memory used on this tab.
What have I missed?
Old Class based file code
listener: any;
componentDidMount() {
const { firebase } = this.props;
this.listener = firebase.onAuthUserListener(
(authUser: any) => {
localStorage.setItem('authUser', JSON.stringify(authUser));
this.setState({ authUser });
},
() => {
localStorage.removeItem('authUser');
this.setState({ authUser: null });
}
);
}
componentWillUnmount() {
this.listener();
}
New with hooks (causing performance issues)
const listener = () => {
firebase.onAuthUserListener(
(authUser: any) => {
localStorage.setItem('authUser', JSON.stringify(authUser));
setState(authUser);
},
() => {
localStorage.removeItem('authUser');
setState(null);
}
);
};
useEffect(() => {
listener();
return () => {
listener();
};
});
It may also be worth noting that I am using TypeScript with React.
onAuthUserListener returns a function to unsubscribe. This should be used when component unmounts.
In your code you are not returning the unsubscribe function.
const listener = () => {
firebase.onAuthUserListener(..) // problem here no return
}
So under the useEffect you should assign it properly and use it in useEffect's return.
const [user, setUser] = React.useState(null);
useEffect(
() => {
// v------ proper assignment.
const listener = firebase.onAuthUserListener(
(authUser: any) => {
localStorage.setItem('authUser', JSON.stringify(authUser));
setUser(authUser);
},
() => {
localStorage.removeItem('authUser');
setUser(null);
}
);
return () => listener();
}
, [] // no deps
);
Here might be the error:
useEffect(() => {
listener();
return () => {
listener(); <--- here
};
});
The question is, what state does need to change in order to trigger a listener(); call?
I think this:
const listener = () => {
firebase.onAuthUserListener(
(authUser: any) => {
localStorage.setItem('authUser', JSON.stringify(authUser));
setState(authUser);
},
() => {
localStorage.removeItem('authUser');
setState(null);
}
);
};
Should be transformed into a React Hook. Cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With