Next.js: Shallow routing: pushing same route keeps rerendering component

Created on 15 Dec 2017  路  8Comments  路  Source: vercel/next.js

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

This issue might be somewhat similar to #2668, however the provided workaround does not fix my problem.

Expected Behavior

Assuming I am at the following route '/docs/imgproc', if I keep on pushing the exact same route, e.g.: router.push('/docs?cvModule=imgproc', '/docs/imgproc#boundingRect', { shallow: true }) I would assume getInitialProps not to be called repeatedly as the route did not change and I am pushing with shallow option.

Current Behavior

The first time I push a new route via: router.push('/docs?cvModule=imgproc', '/docs/imgproc#boundingRect', { shallow: true }) getInitialProps is called as I would expect. However, executing the exact same push again it should not call getInitialProps again, especially with { shallow: true }, or am I missing something here?

Furthermore, looking at router.router.asPath, I get the following: '/docs/imgproc#boundingRect'. If I slightly modify the asPath, e.g.: router.push('/docs?cvModule=imgproc', '/docs/imgproc#bounding', { shallow: true }) getInitialProps is not called, as expected. If I push with the exact same asPath it keeps being called repeatedly.

The above explained behaviour also applies with the 'next/link' component. That's how I initially discovered the issue.

Context

What I want to achieve, is to prevent the page from being rerendered if the route is the same with a different hash value. As { shallow: true } does not seem to work in case the asPath is the same, I assume the only option is to write a custom Link component which parses the asPath and the hash value?

Your Environment

| Tech | Version |
|---------|---------|
| next | 4.1.4 |
| node | 9.2.0 |
| OS | win7 x64 |
| browser | chrome 63.0 |

needs investigation

Most helpful comment

@justadudewhohacks thanks for the repo!.

I can confirm that there is an issue when you try to navigate to a page with a hash value and then redirect to the same page and hash, it works fine if you redirect to a different hash or if you add a hash to the page without previously having had one.

You should use your workaround for now until someone has the time to fix this

All 8 comments

I can't find where the issue is, it's working fine to me in the same version, can you share a repo ?

This occurs when you request a page via next Link with an asPath containing a hash value. Now pushing the same asPath keeps updating the component.

I have set up an example:
https://github.com/justadudewhohacks/nextjs-shallow-routing-issue

I had to work around this issue by writing a custom Link component, which imports Router from 'next/router' and replaces the hash value in the asPath with something unique after pushing the route.

@justadudewhohacks thanks for the repo!.

I can confirm that there is an issue when you try to navigate to a page with a hash value and then redirect to the same page and hash, it works fine if you redirect to a different hash or if you add a hash to the page without previously having had one.

You should use your workaround for now until someone has the time to fix this

This bug appears to be deliberate, although I don't understand the motivation.

You can see the comment and line of code here:

https://github.com/zeit/next.js/blob/canary/packages/next-server/lib/router/router.js#L313-L317

I'm having the same problem with Router.push().
Given that I'm trying to use redux, , every time I try to Router.push from "/search" to "/search/results", a server side render is forced and the redux state is lost.

Once I'm in the current path "/search", I tried Router.push("/search/results", "/search/results", { shallow : true }), but with no success: the new page is rendered on server and the state is lost.

Could you find any solution to that? I believe it's common to put routes in hierarchy like

/search
/search/results
/search/results/details
/search/results/1/
/search/settings

and so on.

With this "bug", I couldn't figure out how to preserve state within a hierarchy like that. Do you have any suggestions?

Also, the project is based on custom server with express.

I'm assuming you're pushing to the wrong route, read this: https://github.com/zeit/next.js/issues/2833#issuecomment-414919347

I'm assuming you're pushing to the wrong route, read this: #2833 (comment)

Thank you! I could make it work.
Actually, the route was fine, but after reading the comment you suggested: href must respect the path in the filesystem. That was the mistake. I was repeating href and as.

This appears to be working fine in the latest version of Next.js. I'm gonna close this issue, if you are still having trouble feel free to comment

Was this page helpful?
0 / 5 - 0 ratings