vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.73k stars 26.94k forks source link

Templates don't rerender when using route groups #52422

Open tom-sherman opened 1 year ago

tom-sherman commented 1 year ago

Verify canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.5.0: Thu Jun  8 22:22:20 PDT 2023; root:xnu-8796.121.3~7/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.13.0
      npm: 8.13.2
      Yarn: 1.22.19
      pnpm: 8.6.6
    Relevant Packages:
      next: 13.4.10-canary.0
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 4.9.4
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue or a replay of the bug

https://github.com/tom-sherman/nextjs-template-route-group-bug

To Reproduce

  1. Add a template in the same route as a route group
  2. Navigate between pages in the group

Describe the Bug

Template should rerender. In the linked reproduction, we should see new random numbers rendered to the screen when navigating between A & B using the links.

Expected Behavior

Template doesn't rerender. Numbers don't change on navigation between A & B

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Fredkiss3 commented 1 year ago

Hello, i tested the code and it seems templates just don't rerender on navigation wether in route groups or not (tested by replacing (group) with /group).

And i think, when the docs means they rerender on navigation, it is only in the client.
As said in the docs, the children of templates are totally replaced (on the client) :

Templates are similar to layouts in that they wrap each child layout or page. Unlike layouts that persist across routes and maintain state, templates create a new instance for each of their children on navigation. This means that when a user navigates between routes that share a template, a new instance of the component is mounted, DOM elements are recreated, state is not preserved, and effects are re-synchronized.

https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#templates

I think in the server side, they behave just like layouts.

Fredkiss3 commented 1 year ago

I created an example with the behavior outlined in the docs : https://github.com/Fredkiss3/next-template-correct-behavior

In the example i just made the nested layout & nested templates as client components. You can see when navigating from one route to another the number on the nested template changes everytime, while it stays the same for the nested layout.

tom-sherman commented 1 year ago

And i think, when the docs means they rerender on navigation, it is only in the client.

Server templates do rerender when they're used in a dynamic segment, but they have to be at the same level as the dynamic page.

https://github.com/tom-sherman/nextjs-template-route-group-bug/commit/bfed21ce22342b0b73ff03cfbedb8424776761ac

I suppose it makes sense, the template in the route group case is receiving only the routeParam that is knows about and using that as the key, it can't know it's child params or routes.

tom-sherman commented 1 year ago

I think in the server side, they behave just like layouts.

Ah, you're right and this makes sense. I guess this is just expected behaviour then

Fredkiss3 commented 1 year ago

Server templates do rerender when they're used in a dynamic segment, but they have to be at the same level as the dynamic page.

I think it is the same for layouts, they need to be aware of the param, so if it changes, the layout needs to rerender (on the server) also.

maiconsanson commented 5 months ago

Hello, i tested the code and it seems templates just don't rerender on navigation wether in route groups or not (tested by replacing (group) with /group).

And i think, when the docs means they rerender on navigation, it is only in the client. As said in the docs, the children of templates are totally replaced (on the client) :

Templates are similar to layouts in that they wrap each child layout or page. Unlike layouts that persist across routes and maintain state, templates create a new instance for each of their children on navigation. This means that when a user navigates between routes that share a template, a new instance of the component is mounted, DOM elements are recreated, state is not preserved, and effects are re-synchronized.

https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#templates

I think in the server side, they behave just like layouts.

Exactly! But if I want to use a template I would expect the DOM elements to be recreated (especially on the server side, that's the main difference of the Layout). This is a bug or is badly documented.

KieronWiltshire commented 2 months ago

This seems like a huge bug. Needs fixing on NextJS 15 before release smh. https://discord.com/channels/752553802359505017/1273716701455847464

There's an issue on discord I posted, I added two videos, one on nextjs 14 and the other on 15. Both videos are using the same code-base just different versions of next. 1 issue seems to be fixed on nextjs 15, whilst the other has not, being that templates do not re-render when within same route groups.