question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

next/router - push function changes between renders when called

See original GitHub issue

Bug report

Depending on the push function of useRouter causes an infinite loop when the push function is called from inside a useEffect

To Reproduce

  1. Set up a catch-all optional dynamic route [[...slug]].js
  2. Render the following component from this page Example component
const BugExample = () => {
    useEffect(() => {
        push('/[[...slug]]', '/123/test', { shallow: true })
        console.log('called');
     },[push])

    return null
}

You will see an infinite loop of called in the console

Expected behavior

Push should be a non-changing reference, so that the react diff algoirithm knows not to call side effects again uneccesarily

System information

  • OS: macOs
  • Browser: Chrome
  • Version of Next.js: 9.5
  • Version of Node.js: 13.2.0

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:49
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

23reactions
dan-cookecommented, Oct 28, 2020

Hi @jamesmosier - I would be of the opinion that the various router methods should be using useCallback

The React hooks lint rule will complain if you do not include all dependencies in the array - we would prefer to not have to disable this lint rule.

21reactions
andrei-hamezacommented, Dec 8, 2021

I can suggest another workaround:

import Router from 'next/router'

// in component
useEffect(() => {
    if (!loggedIn) {
        Router.push('/login')
    }
}, [loggedIn])

Router can be used in useEffect only or outside of the React lifecycles. I understand this is not the best solution but I prefer to use it over eslint-disable-next-line react-hooks/exhaustive-deps.

Some details: https://github.com/vercel/next.js/discussions/18522#discussioncomment-836362

Read more comments on GitHub >

github_iconTop Results From Across the Web

next/router | Next.js
The useState is maintained between renders because the top-level React component, Page , is the same. If you do not want this behavior,...
Read more >
Understanding Next.js routeChangeStart and router events
The getServerSideProps function is supposed to be called when the router.push method changes the URL of the page.
Read more >
Why does router.push reload / re-render the pages with next.js?
I think the issue lies with the next router giving a new instance on every change. You probably have the following code:
Read more >
Refreshing Server-Side Props - Next.js - Josh W Comeau
import { useRouter } from 'next/router';. function SomePage(props) {. const router = useRouter();. // Call this function whenever you want ...
Read more >
Nextjs Router Push causes re render - Reddit
If I useRouter then do a push to a new then the entire page gets re rendered. ... Are you trying to preserve...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found