Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Dir is caching renders even with "dynamic" set to "force-dynamic" #42546

Closed
1 task done
AlexKvazos opened this issue Nov 6, 2022 · 14 comments
Closed
1 task done
Labels
bug Issue was opened via the bug report template.

Comments

@AlexKvazos
Copy link

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
Platform: linux
Arch: x64
Version: #14 SMP Sat Jun 4 00:16:10 CEST 2022
Binaries:
Node: 16.17.0
npm: 8.15.0
Yarn: 1.22.19
pnpm: 7.1.0
Relevant packages:
next: 13.0.2
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0

What browser are you using? (if relevant)

Chrome

How are you deploying your application? (if relevant)

next start

Describe the Bug

When clicking on to go to a page that has "dynamic" segment config set to "force-dynamic" the page still uses a cached render from a previous visit.

Expected Behavior

The "force-dynamic" config should make the page render again each time you visit the page through or any other client side transition.

Link to reproduction

https://stackblitz.com/edit/nextjs-sxijav?file=package.json,app%2Fnested%2Fpage.tsx

To Reproduce

  • Click link to go to the nested page
  • A random number will show
  • Click link to go to home page
  • Click link to go to nested page
  • Bug: Same number shows (Expected: Different number)
@AlexKvazos AlexKvazos added the bug Issue was opened via the bug report template. label Nov 6, 2022
@zenflow
Copy link
Contributor

zenflow commented Nov 6, 2022

Manually setting cache: "no-store" on all the fetch calls doesn't work [to make the page dynamic] either.

@Fredkiss3
Copy link
Contributor

Fredkiss3 commented Nov 7, 2022

It is because of soft navigation, with the new layouts nextjs does soft navigation by default, when your page has not been rendered already and the user navigates to it with a link component, it does not rerender the page each time.

What the nextjs team said is that your page should rerender if you do a mutation with their upcoming mutation, or if you call router.refresh.

It is a PIA i think because the mental model of dynamic pages is that it should rerender each time you go to them.

Update : I tried to disable prefetching of links to force rerendering but it disables client side page navigation, im gonna open an issue for this

@zenflow
Copy link
Contributor

zenflow commented Nov 7, 2022

From the docs link above:

On navigation, Next.js will prioritize using soft navigation if the route you are navigating to has been prefetched, and either doesn't include dynamic segments or has the same dynamic parameters as the current route.

So not only a PITA, it doesn't work when data is dynamic but not dynamic based on route params (i.e. data that changes frequently, or data that changes based on current user / http headers). How are we supposed to force hard navigation in these cases?

Rather than adding more exceptions to the rules of when Next.js will use soft vs hard navigation, I would rather see it simplified.

@AlexKvazos
Copy link
Author

AlexKvazos commented Nov 9, 2022

It does feel misleading that a "force-dynamic" page will still use a soft render. There should be some place in the docs suggesting something like...

useState(() => router.refresh())

Or some other way to have this run on the first render only. I don't think this is very elegant.

@Fredkiss3
Copy link
Contributor

@gfortaine

It looks like that you are doing Client-Side Navigation with a Server Component. Simply add the reactjs/rfcs#227 at the top of the NestedPage component. Then, you will notice that it will trigger a re-render on client-side transition using next/link

There is a problem though : it causes hydration mismatches, as you can see in the screenshot below :

image

And what about data fetching ?
I've tweaked the example and make it fetch a random number instead on the server :
https://stackblitz.com/edit/nextjs-zskblw?file=next.config.js,app%2Fnested%2Fpage.tsx

And wether i add a cache: no-store or next: { revalidate: 0 } it still does a soft navigation and the user needs to reload the page fully to see a different number.

@Fredkiss3
Copy link
Contributor

Fredkiss3 commented Nov 14, 2022

@gfortaine , the solution you’re suggesting is to use the use hook, but this hook lead to infinite fetches, so no it’s not a viable solution, at least for now. Since use is not a stable API right now, and is supposed to come with the cache api in react.

@gfortaine
Copy link
Contributor

gfortaine commented Nov 14, 2022

#42180

@Fredkiss3
Copy link
Contributor

Fredkiss3 commented Nov 14, 2022

Yes use is an experimental, but the RFC hasn’t landed yet and the infinite fetches seems to be more of react issue than NextJs.
I wouldn’t recommend this since it is still heavily in development and the default behaviour now is not optimal.

indeed there is a clear case where it leads to infinite fetches : when we start directly on the /nested path. But clicking on /nested in / is OK. Thus, it looks like that Next.js doesn't handle use very well right now.

Still one odd thing I noticed is that it still does at least 3 or 4 fetches (which is isn’t supposed to be the case, right ?)
At least with the "use client" it should only fetch twice : once in the server and the second time in client during hydration.

But it fetches once in the server and 3 or 4 more in the client.

@gfortaine
Copy link
Contributor

According to the following comment, it seems that one should create a new root layout (/nested) to trigger a hard navigation :

#41745 (reply in thread)

@Fredkiss3
Copy link
Contributor

@gfortaine I've put up an example with that in mind : https://stackblitz.com/edit/nextjs-wxc4fy
But In my opinion, that is some pretty hacky way to solve this. And i don't think this would be a viable solution...

I still think this is not good enough, and they should this fix... or at least indicate in the doc a way around this.

@Fredkiss3
Copy link
Contributor

Fredkiss3 commented Nov 16, 2022

What is weird, is that when using a dynamic route segment, a hard navigation always occurs : https://stackblitz.com/edit/nextjs-51tdbm?file=app%2F[any]%2Fpage.tsx

I think this is indeed a bug

@zenflow
Copy link
Contributor

zenflow commented Nov 16, 2022

What is weird, is that when using a dynamic route segment, a hard navigation always occurs : https://stackblitz.com/edit/nextjs-51tdbm?file=app%2F[any]%2Fpage.tsx

@Fredkiss3 Just pointing out that this is the documented behavior. See https://beta.nextjs.org/docs/routing/linking-and-navigating#soft-navigation :

On navigation, Next.js will prioritize using soft navigation if the route you are navigating to has been prefetched, and either doesn't include dynamic segments or has the same dynamic parameters as the current route.

Of course there's still an issue with this documented behavior..
What are we supposed to do when we have dynamic data that changes frequently? Or data that depends on authentication state? Currently stale data will be shown until user does a manual refresh, or we need some hack to force a "hard refresh" (useState(() => router.refresh()), which, how do we do that and avoid fetching data twice in the cases where data wasn't fetched before?).

@AlexKvazos
Copy link
Author

Closing in favor of #42991

@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

4 participants