-
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
Compound components cause "React.jsx: type is invalid -- expected a string or a class/function" #74585
Comments
React.jsx: type is invalid -- expected a string or a class/function
React.jsx: type is invalid -- expected a string or a class/function
If you mark a file with “use client” and import it from server components the content of the module is replaced with references. You can’t access values off from references - hence it breaks |
Alright, then I guess this might be more suited as a discussion, but could you point me in a direction for how we need to adjust the Equinor EDS core library (current PR: equinor/design-system#3716) to remedy this? As it currently stands, it doesn't work with these compound/namespaced components. Where do we need to add |
I think many of them shouldn’t be marked with “use client” at all because they have unserializable props and they aren’t suitable as boundaries. Check out this MR from React Aria - adobe/react-spectrum#5826 |
But most of these components are very renderable both serverside and clientside, it's just that some of them contain hooks and must therefore have the What does it mean that they have "unserializable props"? |
“use client” isn’t meant for marking client components. It’s supposed to mark client components which are boundaries in the application - these which are used directly from server components. These have additional restrictions, e.g. they need to have serializable props. Serializable props are documented here. So if your component e.g. Popover accepts anchorEl (HTMLElement) or onClose (callback) - these naturally can’t be marked as boundaries. |
Ok, so that's understandable - but does that mean that we can not use these components (components that take HTMLElement or callback as props) at all in our application? How should the library authors make it possible to use these components both in SPA's and (e.g.) Nextjs-applications? Adding a dependency to "client only" seems strange, but is that the only way? And if all that does is raise an error during build time, surely that isn't really a solution either? |
I think that for generic UI libraries such as React Aria or yours (if my brief check is correct) not using “use client” and opting for import client-only is a proper call. These components often can’t be rendered from server component anyway. And you as an author of generic UI library have no idea where boundaries will be in consumer app. At the same time import client-only clearly indicates that some component is meant to be used from client environment and it protects your from adding/removing a hook being a breaking change. |
If I understand correcly, however, the I guess the core of what I'm wondering (and the reason behind this github issue) is: When using the library in SPAs (e.g. built with Vite), it just works, but we've come across quite a few issues we've had to solve to make it "Next.js-compatible". |
The points is that you can’t just wrap all components from your library with “use client”. That’s incorrect, whether you do that or the consumer. AFAIK if your library uses React’s client features and components aren’t created with these additional boundaries restrictions in mind - adding import client-only is the correct solution, despite the additional hassle. I get your point that’s additional friction but I personally think what lacks here mostly is people being aware how this stuff works. |
Ok, we'll have to look closer at whether we want to add However, at the core of the issue (and what started this GitHub-issue) is us not being able to make Hopefully you can see an issue with our current approach when it comes to this as well. This is what my examples are about, mostly. |
I think that could be possible if instead of mutating component and doing |
Alright thank you! I'll close this issue as resolved, and we'll have to have a discussion on how to best support Nextjs in EDS. I suppose simply exposing each components seperately should work fine as well ( Thanks again! |
Link to the code that reproduces this issue
https://github.com/sebastianvitterso/next-compound-component-issues
To Reproduce
Two "ways to break":
First:
npm run dev
."use client"
incomponents/Compound/index.tsx
.Second:
npm run dev
.<Table>
and<Table.Body>
-code inapp/page.tsx
.Video showing:
Screen.Recording.2025-01-07.at.13.48.40.mov
Current vs. Expected behavior
For some reason, compound components "randomly" break when used in conjunction with
"use client"
-components within server-side pages.Expectation: No error, just works.
Provide environment information
Which area(s) are affected? (Select all that apply)
Not sure
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
No response
The text was updated successfully, but these errors were encountered: