I have one warning in the console for my React app that mentions a memory leak with instructions. I'm not sure how to refactor my code to incorporate componentWillUnmount.
I do have useEffect() and JS promise code to pull and render data from a Firebase database but the error does not mention that component.
Please read the full warning error below here:
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 Nav (at Home.js:32)
in div (at Home.js:30)
in DashHome (created by Context.Consumer)
Nav.js code:
class Nav extends Component {
state = {
isSignedIn: true
}
componentDidMount = () => {
firebase.auth().onAuthStateChanged(user => {
this.setState({ isSignedIn: user })
})
}
render() {
return (
<div className="side-nav">
<Nav vertical>
<NavItem>
<NavLink href="#">Home</NavLink>
</NavItem>
{this.state.isSignedIn ? (
<div>
<Button onClick={() => firebase.auth().signOut()}>Sign-out</Button>
</div>
) : (
<Redirect to="/" />
)}
</Nav>
</div>
);
}
}
export default Nav;
Home.js component (some code)
export default function Home() {
const generateData = (value, length = 5) =>
d3.range(length).map((item, index) => ({
date: index,
value: value === null || value === undefined ? Math.random() * 100 : value
}));
const [data, setData] = useState(generateData(0));
const changeData = () => {
setData(generateData());
};
useEffect(
() => {
setData(generateData());
},
[!data]
);
I read about AbortController API in a tutorial but I'm not using Fetch in my app.
Thank you for taking a look! Please feel free to post any code refactoring ideas to resolve this.
The function returns an unsubscribe function when you call it.
var unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
// handle it
});
You should call this function in componentWillUnmount like this.
let unsubscribe;
class Nav extends Component {
state = {
isSignedIn: true
}
componentDidMount = () => {
unsubscribe = firebase.auth().onAuthStateChanged(user => {
this.setState({
isSignedIn: user
})
})
}
componentWillUnmount() {
unsubscribe()
}