-
Notifications
You must be signed in to change notification settings - Fork 28.9k
Description
Link to the code that reproduces this issue
https://github.com/darthmaim-reproductions/vercel-next.js-72034
To Reproduce
- Clone the reproduction
npm i
npm run dev
- Open http://localhost:3000/ and observe error
Current vs. Expected behavior
Current
Expand to see relevant code
import { FC } from "react";
import { ClientComponent } from "./client-component";
export default function Home() {
return (
<ClientComponent>
<ServerComponent/>
</ClientComponent>
);
}
const ServerComponent: FC = async () => <div>server component</div>
'use client'
import { cloneElement, FC, ReactElement, use } from "react"
export const ClientComponent: FC<{ children: ReactElement }> = ({ children }) => {
// @ts-ignore uncomment the next line for a workaround
// if(children.$$typeof === Symbol.for('react.lazy')) { children = use(children._payload); }
return cloneElement(children, {
ref: (element) => console.log('ref', element)
})
}
When using cloneElement
in a client component, and the children is an async server component, this error is thrown:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method ofClientComponent
.
When the server component is not async
(or a client component), this just works.
Additionally, adding this line to the client component also makes this work:
if(children.$$typeof === Symbol.for('react.lazy')) { children = use(children._payload); }
Expected
Since cloneElement
works for client components and non-async server components, I expected this to work async server components as well.
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 21.6.0: Mon Jun 24 00:56:10 PDT 2024; root:xnu-8020.240.18.709.2~1/RELEASE_X86_64
Available memory (MB): 16384
Available CPU cores: 4
Binaries:
Node: 22.8.0
npm: 10.8.2
Yarn: N/A
pnpm: N/A
Relevant Packages:
next: 15.0.2-canary.11 // Latest available version is detected (15.0.2-canary.11).
eslint-config-next: N/A
react: 19.0.0-rc-02c0e824-20241028
react-dom: 19.0.0-rc-02c0e824-20241028
typescript: 5.3.3
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Not sure
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local)
Additional context
This might be a bug in react and not in Next.js.
In earlier versions the children was reported as <Lazy/>
in react-dev-tools and cloneElement
was working, now it is shown as { $$typeof: Symbol(react.lazy) }
(when not using cloneElement to avoid the error).