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

Hovering a prefetch Link causes unnecessary re-render of the error boundary in production #63159

Closed
ChaserZ98 opened this issue Mar 11, 2024 · 5 comments · Fixed by #64575
Closed
Labels
bug Issue was opened via the bug report template. locked

Comments

@ChaserZ98
Copy link

Link to the code that reproduces this issue

https://github.com/ChaserZ98/next-error-link-rerender-bug

To Reproduce

  1. Run npm run build
  2. Run npm run start
  3. Visit any page which may produce an error such as http://localhost:3000/link1 of the reproduction project.
  4. Trigger the error such as clicking the button in http://localhost:3000/link1 page of the reproduction project.
  5. Hover any Link with prefetch enabled.

Current vs. Expected behavior

Current behavior

  • Hovering any Link with prefetch enabled will trigger a re-render of the error boundary but non-prefetch Links won't trigger such re-render.
  • As for the reproduction project, I include console.log("error render") in the error boundary so that the console will print error render each time the error boundary is rendered. So in this case, the users will see the console printing error render when they hovering any prefetch Link.
  • Such behavior is present in the production build but not present in the development stage, i.e. npm run dev.

Expected behavior

Hovering any Link that does not trigger a state change should not cause the error boundary to re-render, no matter it is a prefetch link or non-prefetch Link.

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 10 Home
Binaries:
  Node: v18.18.2
  npm: 10.2.4
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 14.2.0-canary.13
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router

Which stage(s) are affected? (Select all that apply)

next build (local), next start (local)

Additional context

The behavior is present in release 14.0.2-canary.7 and above.
A similar issue might be #58788 . But the fix for that issue isn't working for this one since such behavior still presents in the latest canary release, which is 14.2.0-canary.15 by the time this issue is posted.

@ChaserZ98 ChaserZ98 added the bug Issue was opened via the bug report template. label Mar 11, 2024
@samcx
Copy link
Member

samcx commented Apr 16, 2024

@ChaserZ98 Can confirm this is an issue. We are taking a look!

@ChaserZ98
Copy link
Author

@samcx Thanks! Let me know if any details are needed for this issue. Looking forward to a fix!

ztanner added a commit that referenced this issue Apr 16, 2024
Since `AppRouterState` is promise-based (so we can `use` the values and
suspend in render), the state itself isn't stable between renders. Each
action corresponds with a new Promise object. When a link is hovered, a
prefetch action is dispatched, even if the prefetch never happens (for
example, if there's already a prefetch entry in the cache, and it
doesn't need to prefetch again). In other words, the prefetch action
will be dispatched but won't necessarily change the state.

This means that these no-op actions that don't actually change the state
values will trigger a re-render. Most of the context providers in
`AppRouter` are memoized with the exception of `LayoutRouter` context.
This PR memoizes those values so that consumers are only notified of
meaningful updates.

Fixes #63159


Closes NEXT-3127
@samcx
Copy link
Member

samcx commented Apr 17, 2024

@ChaserZ98 This should be :fixed: in v14.3.0-canary.7! Let us know if you can confirm.

@ChaserZ98
Copy link
Author

@samcx I did the check in v14.3.0-canary.7 and the latest canary version, which is v14.3.0-canary.8 by the time of this reply. Such re-render behavior caused by prefetch Link does not show up anymore. The issue is solved. Perfect work! Thanks!

Copy link
Contributor

github-actions bot commented May 2, 2024

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 added the locked label May 2, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 2, 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

Successfully merging a pull request may close this issue.

2 participants