-
Notifications
You must be signed in to change notification settings - Fork 27.5k
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
Calling a server action during render tries to update Router
component, causing an error
#75374
Comments
The new Router is fully integrated with React. In practical terms, that means that it uses React state, namely, a And just like you shouldn't call So, what I think is happening here is that, the act of calling an action, updates the actionQueue, which leads to this issue. Where is it stated that one can call |
@icyJoseph Thank you for the reply!
Where is it stated that you can't? I realize there is still ongoing work around Also, I observed that "delaying" the server action call with --- a/app/client-components.tsx
+++ b/app/client-components.tsx
@@ -1,12 +1,17 @@
'use client'
-import { use } from "react"
+import { use, useEffect, useState } from "react"
import { getValue } from "./server-actions"
let cachedPromise: Promise<string>
export function Demo() {
- cachedPromise ??= getValue()
+ // Avoid server action during SSR; avoid hydration error.
+ const [isFirstRender, setIsFirstRender] = useState(true)
+ useEffect(() => { setIsFirstRender(false) }, [])
+ if (isFirstRender) return null
+
+ cachedPromise ??= Promise.resolve().then(() => getValue())
const value = use(cachedPromise)
return <div>{value}</div>
} I wouldn't rely on that behavior in production code, but it hints at the possibility of deferring the internal |
Why wouldn't you use
Which is also fun, because, there's this other issue, #69265, which is also kind of counter intuitive. |
Yes, I know that they are not recommended for data fetching, but they are not prohibited, and some people are using them for that purpose. Server functions + React serialization format can provide a magical DX compared to Long term, I think there will eventually be a variant of server functions designed for data fetching (i.e. parallelizable, cacheable). I've seen a proposal to special case server functions based on naming convention, for example using HTTP |
Right... And they are calling them server functions now, but calling them as you render is not the same as coupling to them in effects and such. Those are my two cents anyway. |
Link to the code that reproduces this issue
https://codesandbox.io/p/devbox/crazy-field-gnyj7q
To Reproduce
Visit the reproduction app.
In the app preview, see the Next.js error pop-up:
Note that there is no explicit
setState()
call inside the component.Current vs. Expected behavior
Currently, calling a server action during a render causes a React error (see above).
The expected behavior is that the server action returns a
Promise
(without causing a React error), and that thePromise
, if properly cached, can be consumed withuse
(without causing a React error).Provide environment information
Operating System: Platform: linux Arch: x64 Version: #1 SMP PREEMPT_DYNAMIC Sun Aug 6 20:05:33 UTC 2023 Available memory (MB): 4102 Available CPU cores: 2 Binaries: Node: 20.9.0 npm: 9.8.1 Yarn: 1.22.19 pnpm: 8.10.2 Relevant Packages: next: 15.2.0-canary.27 // Latest available version is detected (15.2.0-canary.27). eslint-config-next: N/A react: 19.0.0 react-dom: 19.0.0 typescript: 5.3.3 Next.js Config: output: N/A
Which area(s) are affected? (Select all that apply)
Runtime
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local)
Additional context
No response
The text was updated successfully, but these errors were encountered: