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

Nested layouts on a dynamic segment are re-mounted when navigating between them #44793

Closed
1 task done
floatingdino opened this issue Jan 12, 2023 · 11 comments
Closed
1 task done
Labels
bug Issue was opened via the bug report template. locked

Comments

@floatingdino
Copy link

Verify canary release

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

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 21.6.0: Wed Aug 10 14:28:23 PDT 2022; root:xnu-8020.141.5~2/RELEASE_ARM64_T6000
Binaries:
  Node: 17.4.0
  npm: 8.3.1
  Yarn: N/A
  pnpm: 6.11.0
Relevant packages:
  next: 13.1.2-canary.5
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0

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

App directory (appDir: true), Routing (next/router, next/navigation, next/link)

Link to the code that reproduces this issue

https://codesandbox.io/s/optimistic-forest-citt6o?file=/pages/index.tsx

To Reproduce

  1. Go to a route that uses nested + dynamic routes
  2. Enter text into an input in the outer and inner layout components
  3. Use next/link to visit another route that uses the same layout components

Describe the Bug

When using Next@13 app directory, layout components inside a dynamic route are re-mounted when navigating to a route with the same layout stack.

Expected Behavior

When navigating between two pages using the same layout stack, the layout is not re-mounted.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@floatingdino floatingdino added the bug Issue was opened via the bug report template. label Jan 12, 2023
@Fredkiss3
Copy link
Contributor

Fredkiss3 commented Jan 13, 2023

That is normal, since your layout is in the same folder as the dynamic segment, the layout will also depend on the parameter [slug], so if [slug] changes all the pages and layouts will also change.

You can see for yourself by adding a params: { slug } argument to your Layout, it will rerender everytime (on the server) :

// app/test/[slug]/layout.tsx
export default function TestLayout({ children, params: { slug } }) {
  console.log({ slug })
  return (
    <>
      <input className="border" />
      {children}
    </>
  );
}

If you want a Layout that persist between slug changes, you could either use the layout one level up in the tree :

.
└── app/
    └── test/
         ├── layout.tsx <-- this here
         └── [slug]/
              └── page.tsx

Or if you want a specific layout for your dynamic pages, you can create a route group :

.
└── app/
    └── test/
        ├── layout.tsx
        └── (group)/
             ├── layout.tsx <-- this here
             └── [slug]/
                  └── page.tsx

@floatingdino
Copy link
Author

I see - do you know why it re-mounts the component rather than just passing down new props? In my specific use case I need access to the slug value inside the layout and I'd rather not extract if from the pathname if I can avoid it.

@Fredkiss3
Copy link
Contributor

The whole layout get unmounted and remounted, i think. You already have access to the slug in the layout and it is even passed to page.

@HriBB
Copy link

HriBB commented May 22, 2023

The whole layout get unmounted and remounted, i think. You already have access to the slug in the layout and it is even passed to page.

I have a similar problem. I have a canvas, which is unmounted and mounted on url change. I want to define a layout that has access to [...slugs] param, but wont re-mount on change. How can I achieve that?

Screencast.from.2023-05-22.20-41-09.webm

@ArjobanSingh
Copy link

Hey @HriBB,
Did you find any solution for this? I've same problem, I am using @monaco-editor/react on one of the children routes, but on every route change, it remounts, thus making the inner <Editor /> component to remount, which loads everytime and shows a loading flicker, similar to your canvas problem.

Did you find any workaround for preventing the child page's remount, rather only re-render.

@HriBB
Copy link

HriBB commented Jul 13, 2023

@ArjobanSingh I could not find a solution, so I switched to Remix, and got it working immediately.

@M7ilan
Copy link

M7ilan commented Dec 31, 2023

Hello, I have the same issue but I use parallel routes.
This is the stracture of my app:

[app]
    ├── globals.css
    ├── layout.tsx
    └── [route]
        └── [[[...slug]]]
            ├── [@Books]
                └── page.tsx
            ├── [@Content]
                └── page.tsx
            ├── [@Records]
                └── page.tsx
            ├── [@Title]
                └── page.tsx
            └── layout.tsx

Sample app https://issue-60037.vercel.app/

listlessbird added a commit to listlessbird/keeparr that referenced this issue Jul 15, 2024
…route group

this prevents rerenders when document is changed from sidebar happens because anything under a dynamic route gets rerendered when the url is changed.

[ref](vercel/next.js#44793 (comment))
listlessbird added a commit to listlessbird/keeparr that referenced this issue Jul 15, 2024
* feat: setup tests

* feat: use clamp for fontsizes

* fix(tooling): classname sorting

* feat: setup initial notes ui

* feat(notes): add editor

* refactor(notes): refactor the sidebar to a parallel route

* feat: wip style up a tree component

fix: add padding

* feat([notes- wip]): create note structure

* fix: move nav to layout

- refactore component name

* feat(notes)!: change notes to a map

- chore: mock from backend

* feat: load notes from sidebar

* chore: regenerate lock file

* feat: render tree from server

* fix: grow the layout to the parent's size

* feat: update description in layout.tsx

* chore: update next-themes and zod

* fix: dark theme styles

* chore: debug setup

* feat: get notes from the server and list on file tree

* fix: use client side fetch for notes
feat: add loading state while switching notes

* feat: update API URL in note query to use URL from env

* feat: empty note dashboard page

* chore: remove unneeded package

* feat: note dashboard

* fix: sidebar parallel route

* feat: Update NoteItem type and refactor related code

The NoteItem type has been added to the note module, and the code has been refactored to use this type instead of the Note class.

* feat: use indexed db to save content locally

* refactor: update NotePlayGround component to save note updates in indexedDB

The NotePlayGround component has been updated to save note updates in indexedDB using the iDBPutNote function. This ensures that changes made to the note content are persisted locally. Additionally, the setUpdated method has been added to the Note class to update the updatedAt property when a note is modified.

Related recent commits:
- feat: use indexed db to save content locally
- feat: Update NoteItem type and refactor related code

* refactor: save note contents in every x interval

maybe i could do this for every x keystrokes instead (todo?)

* feat: create new note from the sidebar filetree

* fix: text truncation on the `TreeItem` component

* refactor: add ClickToEdit component to TreeItem for editable node names

* fix: use a defaut note schema for new notes to fix crash when notes are empty

* feat: scroll area for notes on sidebar also use Input to handle name edits

* fix: handle space key press in useEditOnClick hook

The useEditOnClick hook now handles the space key press event to append a space character to the input value. This is a temporary fix until the issue with filetree input handling is resolved.

Related recent commits:
- refactor: add ClickToEdit component to TreeItem for editable node names
- fix: text truncation on the `TreeItem` component

* feat: update note on server

* fix: add missing white space between tree items for better visual hierarchy

* feat: editor sync state indicator

shows whether the document is synced to the indexedDB

* feat: actually implement auto save and manual save and move `useNotes` into the nearest common hook directory

* feat: Add sync button to NotesNav component

This commit adds a sync button to the NotesNav component in order to provide manual saving functionality. The sync button's appearance and behavior are determined by the syncStatus prop, which can have three possible values: "unsynced", "synced", or "saving". The button is disabled when the syncStatus is "synced" or "saving". Clicking the button triggers the manualSave function.

Related recent commits:
- feat: actually implement auto save and manual save and move `useNotes` into the nearest common hook directory
- feat: editor sync state indicator

* chore: Remove unused imports and fix an import path

* refactor: move editor related functionalities (sidebar etc) to a new route group

this prevents rerenders when document is changed from sidebar happens because anything under a dynamic route gets rerendered when the url is changed.

[ref](vercel/next.js#44793 (comment))
@mira-hariri
Copy link

mira-hariri commented Aug 4, 2024

@Fredkiss3 Hello, I am facing re-rending issue as well
When running my Next app locally everything is working fine, but when I deployed it on vercel I faced re-rendering of the layout that is inside the route group
this is my file structure
image

the layout in the root file is working fine, but the layout in the (protected) group is re-rendering when navigating between the grouped pages (pets,home,posts,profile)

@ApplY3D
Copy link

ApplY3D commented Nov 27, 2024

@floatingdino in which version this was fixed?

@floatingdino
Copy link
Author

@ApplY3D this is the intended behaviour AFAIK. It's not a bug.

Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for 2 weeks. 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 Dec 12, 2024
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. locked
Projects
None yet
Development

No branches or pull requests

7 participants