Issue of Using router as a Dependency in useEffect
Adam C. |

Using "router" as a Dependency is useEffect is dangerous because it could cause an infinite page re-rendering. The better to fix this is using "Router" directly imported from "next/router"

Photo by Lysander Yuen on Unsplash

The issue was discovered when I tried to reset the parameter in a URL, and I used the following code:

import { useRouter } from "next/router";
export default function TimeTable () {
	const router = useRouter();
	useEffect(() => {
  		// refetch data since option changed
  		// then reset the pagination
  		router.push("?page=" + 1, undefined, { shallow: true });
	}, [option])
}

Which works fine, but ESLint clearly complains about this:

React Hook useEffect has a missing dependency: 'router'. Either include it or remove the dependency array. react-hooks/exhaustive-deps

So I added the router as:

import { useRouter } from "next/router";
export default function TimeTable () {
	const router = useRouter();
	useEffect(() => {
  		// refetch data since option changed
  		// then reset the pagination
  		router.push("?page=" + 1, undefined, { shallow: true });
	}, [option, router])
}

Cool, the ESlint does not complain about this anymore. However, the worst thing happens: the page is re-rendering crazily. 

Here is the long discussion, if you have this issue: 

https://github.com/vercel/next.js/discussions/29403

I borrowed @icyJoseph's solution to fix this:

import Router from "next/router";

export default function TimeTable () {
	useEffect(() => {
  		// refetch data since option changed
  		// then reset the pagination
  		Router.push("?page=" + 1, undefined, { shallow: true });
	}, [option])
}

I know this is not optimal, but it is our job as developers to recognise which tool is best for the job at hand. The Router instance is specially important, because you may want to interact with the Router (listen to events for example), outside of React's, at top of modules, or in Class Components. 

useRouter is still very useful for things that keep track of route changes, query changes, and so on, it is just a matter of recognising when a side-effect could end up in a runaway effect.