vercel / next.js

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

Suspense fallback not being displayed when updating query params and having multiple suspenses in a single page #62049

Open diogo-felix-martins-t opened 5 months ago

diogo-felix-martins-t commented 5 months ago

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/jolly-grass-5t82t8

To Reproduce

  1. Start the application
  2. Click the "Update Query Params" button
  3. No loading will be shown
  4. Remove the"FirstAsyncComponent" from the page
  5. Click the "Update Query Params" button
    • Now the loading is displayed properly as soon as we click the button

Current vs. Expected behavior

Current behaviour

Expected behaviour

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000
Binaries:
  Node: 20.4.0
  npm: 9.7.2
  Yarn: 1.22.18
  pnpm: 8.6.2
Relevant Packages:
  next: 14.1.0
  eslint-config-next: 14.0.4
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.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 dev (local), next build (local), next start (local), Vercel (Deployed), Other (Deployed)

Additional context

No response

diogo-felix-martins-t commented 5 months ago

With the exact same code but with the first component commented out, the fallback works as intended.

Also after some more testing we found out that if we update the key of every suspense in the page it also works. But for our use case we want each suspense to only have their filters from the query params as the key.

JoaoPedroBelo commented 5 months ago

I have exactly the same issue

Jaimayal commented 4 months ago

Same issue here. I've also tried using Parallel Routes but the behavior is the same.

I have been testing for a little bit and found that if the async operations ran inside the first Suspense boundary's content take longer than the other it somehow renders its Loading state, this happens ONLY AFTER the second Suspense boundary finishes its async operations. This also means that the second Suspense's content is re-running its code again.

You can test this by adding delay inside the FIRST <Suspense>'s content, using, for example, await new Promise((resolve) => setTimeout(resolve, 10000));

Aldo-Garza commented 4 months ago

Same issue, blocking form using two tables using queryParams on the same page.

jose-vilasboas-rlabs commented 3 months ago

I think I have a similar issue.

I have two different areas in a page that are affected by different searchParams.

Button A change the searchParam A that is filtering Area A. Button B change the searchParam B that is filtering Area B.

I have a Suspense over Area A with searchParam A as a key. I have a Suspense over Area B with searchParam B as a key.

If I click Button A, the page wil only respond when Area B ends its async processment. If I click Button B. the page will only respond when Area A ends its async processment. (At least it seems that this is the current behaviour)

The solution to get the page respond instantly (showing the Suspense fallback of the affected area) is to add both searchParams as the keys of both Suspense, but this will make both areas to load again even if their filter weren't changed.

Can we make a page to answer instantly if the Suspense keys on it doesn't change? Or at least add some kind of configuration to the Suspense in order to make it behave like that?

adabriand commented 2 weeks ago

Hi everyone,

We've encountered the same issue and found a solution using the useTransition hook.

Here's how we approached it:

  1. Wrap router.push with startTransition.
  2. Use the isPending flag to manage and render the loading state.

I hope this method helps. We’re using this solution while we wait for the Next team’s input here.

JackPriceBurns commented 2 weeks ago

Also experiencing this exact same issue on the latest version of Next.js. I've tried using <Link> router.push and router.replace however they all seem the same. It just seems like when only the searchParams is updated it doesn't perform a full page navigation, it tries to do something fancy which I don't want. I want it to load the page normally and trigger all the <Suspense>'s I have lined up however it just does them all sychronous and will wait for everything to finish before navigating.