next.js
4d3a02d8 - Allow server functions to be used as client component props in `'use cache'` (#81431)

Commit
292 days ago
Allow server functions to be used as client component props in `'use cache'` (#81431) When passing server actions or nested `'use cache'` functions inside of cached components as props to client components, we need to make sure that those are registered as server references, even when restoring the parent component from the cache, e.g. during the resume of a partially static shell. Otherwise, React would throw a runtime error while trying to serialize the props. <details> <summary>Example</summary> ```tsx import { connection } from 'next/server' import { Suspense } from 'react' export default function Page() { return ( <div> <Suspense fallback={<h1>Loading...</h1>}> <Dynamic /> </Suspense> <CachedForm /> </div> ) } const Dynamic = async () => { await connection() return <h1>Dynamic</h1> } async function CachedForm() { 'use cache' return ( <form action={async () => { 'use server' console.log('Hello, World!') }} > <button>Submit</button> </form> ) } ``` </details> Previously, for inline server functions, the Next.js compiler placed the `registerServerReference` calls where the server function was originally declared. When the enclosing function was restored from a cache, this call was skipped and the reference was not registered, leading to the serialization error. To fix it, we can hoist the `registerServerReference` call into the module scope, where the reference itself also has been hoisted to. For simplicity, we're doing this now generally, regardless of whether the server function is inline or top-level. Note: Since `registerServerReference` uses `Object.defineProperties` to mutate the given reference, we don't need to assign the result to anything. We already did this for exported functions of a module with a top-level `'use server'` directive. closes NAR-167
Author
Parents
Loading