-
Notifications
You must be signed in to change notification settings - Fork 27.2k
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
Docs: How to use react cache with server actions if "use server" files only allow async exports? #62860
Comments
ref: #62821 (comment) |
What’s the use case of caching a mutation function (Server Action)? I think "use server"
const getUser = cache(_getUser)
export async function deleteUser(name) {
const user = await getUser(name)
await db.delete(user.id)
await getUser(name) // this won’t return any cache (and shouldn’t)
} |
Okay, I see. Seems like the problem is more about project structure / code organization. So far I haven't used "use server" files exclusively for mutations. I have one "use server" file per entity and this file includes "get" and "post" requests. I use React cache for the "get" requests. Seems like this structure won't work anymore and I need to create separate files for get and post requests. /edit: To elaborate a bit on that: I have interpreted 'use server' as a message to the bundler that the code in this file should only run on the server. Now after reading your message, I assume that I should have two files - one with Is the implication here that |
I do agree that you not suppose to use React cache with server action, as it literally does nothing. However, library that produces server action (async function) will cause the same error as well, as the code will get transpiled into Promise instead of |
I understand that caching mutations does nothing, but why limit this? It breaks colocation of getters and setters in a single file. |
This is an absolute breaking change. I use React.cache to colocated getters (accessed in server components) and mutations. |
Workaround, drop-in replacement for import { cache as reactCache } from 'react'
export const cache = fn => {
const cachedFn = reactCache(fn)
return async (...params) => {
return await cachedFn(...params)
}
} |
I'm not sure about the details, but chances are we are not supposed to call import { cache } from 'react'
const _fn = cache(async () => {
return "...";
})
export const fn = async (...params) => {
return _fn(...params)
} |
Your code is useful when you colocate the cached function inside the server actions file. My version is a utility you could use as a dropin replacement to React.cache
Tested, works perfectly. The only requirement is that the cached function shouldn't change identity so that's why I create |
Looks like the stricter "use server" check has been reverted in the latest canary version #63200. In the meantime, you can use this wrapper to workaround any async function produced by the library function asyncFunction<T extends (...params: any[]) => Promise<any>>(fn: T) {
return async (...params: Parameters<T>) => fn(...params);
} |
The It's totally fine to co-locate data access utilities, however this requirement still applies and we need to be careful. All functions exported from a |
For problems like #62821, #62860 and other, the only way to improve the DX would be relying on the type checker to ensure that Server Actions are async functions. Inlined definitions will always be checked by SWC (as they're always syntactically defined as functions already), but export values are sometimes determined at the runtime. Also added `react-dom` related methods to the disallow list for the server layer. Examples: https://github.com/vercel/next.js/assets/3676859/ac0b12fa-829b-42a4-a4c6-e1c321b68a8e https://github.com/vercel/next.js/assets/3676859/2e2e3ab8-6743-4281-9783-30bd2a82fb5c https://github.com/vercel/next.js/assets/3676859/b61a4c0a-1ad4-4ad6-9d50-311ef3450e13 Closes NEXT-2913
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. |
What is the improvement or update you wish to see?
From 14.1.2 "use server" files only allow async exports. How can we utilize react cache now?
Is there any context that might help us understand?
#62821
Does the docs page already exist? Please link to it.
No response
The text was updated successfully, but these errors were encountered: