How to solve Can't perform a React state update on an unmounted component in Next.js

Cover Image for How to solve Can't perform a React state update on an unmounted component in Next.js
Ali Bentaleb

When we update state on a React component, we want to make sure that the component is mounted first before altering its state

In this tutorial, we are going to:

  • Reproduce the React Error Can’t perform a React state update on an unmounted component in a Next.js project
  • Present how to solve this error

Reproduce error

To reproduce this error, we are going to build two pages:

- the first page ( test.js) will set some data when the route change has completed and has a link to page1 - the second page (tes1.js) will contain a link back to (page.js)

pages/test.js

import {useEffect, useState} from 'react';
import Link from 'next/link';
import Router from 'next/router';

export default function Source() {
	const [data, setData] = useState('');

	useEffect(() => {
		const callData = async () => {
			const data = await fetch(
				'https://jsonplaceholder.typicode.com/todos/10'
			).then((data) => data.json());
			setData(data);
		};
		Router.onRouteChangeComplete = () => {
			setData(data);
		};
		callData();
	}, []);

	return data === '' ? (
		<>loading ... </>
	) : (
		<div>
			{data.title}
			<hr />

			<Link href="/test1">
				<a>test1</a>
			</Link>
		</div>
	);
}

pages/test1.js

import Link from 'next/link';

const Destination = () => {
	return (
		<div>
			Hello <hr />
			<Link href="/test">
				<a>back </a>
			</Link>
		</div>
	);
};

export default Destination;

Now when we click on the link to go to (test1.js), the error message is displayed as below

So the situation is that we have two components, one is called Source which has a link to component Destination

Source component is trying to update its state when component Destination is rendered

the update state happens when we call onRouteChangeComplete and we try to update data in the Source Component

React error on updating an unmounted component ( can't perform a react state update on an unmounted component)

Solve can’t perform a react state update on an unmounted component

To solve this situation, we want to make sure that state updates which usually done using React hook useState are called only when the component is mounted

In our situation, we will fix this issue by cancelling all subscriptions in useEffect cleanup.

To do so, before updating any state we test if the useEffect has done and so cancel all state updated at that moment

Let’s take a look

import {useEffect, useState} from 'react';
import Link from 'next/link';
import Router from 'next/router';

export default function Source() {
	const [data, setData] = useState('');

	useEffect(() => {
		let isSubscribed = true;

		const callData = async () => {
			const data = await fetch(
				'https://jsonplaceholder.typicode.com/todos/10'
			).then((data) => data.json());
			setData(data);
		};

		Router.onRouteChangeComplete = () => {
			isSubscribed ? setData(data) : '';
		};

		callData();

		return () => (isSubscribed = false);
	}, []);

	return data === '' ? (
		<>loading ... </>
	) : (
		<div>
			{data.title}
			<hr />
			<Link href="/test1">
				<a>test1</a>
			</Link>
		</div>
	);
}

The setData is made only before useEffect has returned, and in that way we prevent performing state updates on an unmounted components

Now, test again and inspect the console when clicking on the link, you should see a clear console with no errors.

Conclusion

We have seen how to resolve can’t perform a React state update on an unmounted component in React based project like Next.js

I hope this will help you eliminate this warning

How to build animated spinner ...How to useContext to share Rea...


More interesting articles