-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
[Bug]: Infinite re-render for async RSC stories #30317
Comments
** Disclaimer** This information might be inaccurate, due to it being generated automatically
|
Upon further testing, it seems to be happening on older versions (~8.4.7) as well for this specific minimal repro 🤔 For the best context on my original concern, the way I discovered it is by experimenting with the issue outlined here on the newest release of Storybook: amannn/next-intl#771 (reply in thread).
In this specific example, both Hence me opening this issue. There is probably a lot more underground currents here re: RSC/Suspense/etc that I am not seeing, so just trying to provide as much info as possible to help isolate and troubleshoot here. |
Hi @dmitrc, Thanks for posting the issue. I read through the |
Thanks @valentinpalkovic,
Also added some other components to play around with, including async no await and fake await (actually sync). Please let me know if I can clarify anything further or help in any way!
|
Likely a duplicate of #30033 |
See my comment there on #30033 Here is the diff between next.js v15.0.4-canary.26 and v15.0.4-canary.27 In my environment, I've isolated the regression behavior in storybook to this change. In other words when I revert my Next.JS version to v15.0.4-canary.26 it works. When I upgrade to v15.0.4-canary.27 it starts failing as the OP described. This Next.JS diff includes a React upgrade from 19.0.0-rc-380f5d67-20241113 to 19.0.0-rc-b01722d5-20241114. Here is the diff for those react versions which represents going from React RC 0 to React RC 1. Here is a post about React 19 RC 1 from the React team. It seems the big difference is that the React 19 enableSiblingPrerendering feature flag is switched to true. Not sure yet how or why this affects Storybook the way it does: causing infinite Suspense loops in RSC components. |
Thanks for looking into it, @boylec! It seems there are two distinct issues described in this thread:
|
Acknowledging that Storybook's handling of RSC is kind of funky to begin with, do we know if recent changes to Storybook contributed to these latest problems? Or are these entirely due to upgrading the version of React? |
I don't know the problem of losing the upstream context of the latter... |
EDIT: In hindsight, I would expect that the behavior of the Uncached component in @davidcarr-au 's example is by design. If you call the 'use' hook with a newly instantiated promise on each invocation, it should be expected to suspend infinitely. I think one should always pass the same instance to the 'use' hook if one expects it to eventually exit the suspense state. |
Digging deeper (specifically the infinite render issue in React 19-rc1), here’s my understanding: Pre-RC1: RC1: This is not exclusive to the new 'use' hook, same deal with rendering nested async components using the traditional await data-fetching pattern inside a Suspense boundary. Each render instantiates a new Promise, destabilizing the boundary and causing React to repeatedly suspend and re-render. In Nextjs, server actions make this behaviour stable by resolving data on the server, preventing the client from generating new Promises during rendering. However, Storybook doesn’t have this advantage, as it runs purely client-side, exposing issues with unstable async functions or Promises. So we can use promises and async components like we did pre-rc1 within storybook, but it requires a stabilisation mechanism, hence why the singleton example i provided worked, i've resorted to running calls through a middleware to cache the promise and then remove it on first re-request when mocked for storybook. FYI the React docs also highlight this caveat: client-side Promises recreated on each render will cause unnecessary re-suspends: |
Describe the bug
There was always some funkiness around using
await
in RSC story renders in Storybook (eg see amannn/next-intl#771 (comment)), but in the version 8.5.0+ the behavior has changed for the worse.Now if I have a server component with
await
in it, some recent change on the Storybook side seems to be causing an infinite render. It's a bit tricky to point out what factor exactly causes this, as in my isolated repro even a singleawait
is enough to trigger it, whereas in my actual codebase it only seems to happen when there are 2+.Reproduction link
https://github.com/dmitrc/storybook-repro
Reproduction steps
Or setup from scratch:
.storybook/main.ts:
page.tsx:
ServerComponentWithOneAwait.stories.tsx:
System
Additional context
No response
The text was updated successfully, but these errors were encountered: