Props must be serializable for components in "use client" file #46795
-
SummaryI'm getting the error As seen below, both of the components are marked as client components, yet, I am still getting this error on the Additional informationparent.tsx
"use client";
import { Message } from "@prisma/client";
import React, { useState, useEffect } from "react";
import MessageInput from "./MessageInput";
type Props = {
initialMessages: Message[];
};
export default function MessagesContainer({ initialMessages }: Props) {
const [messages, setMessages] = useState(initialMessages);
return (
<div className="flex flex-col items-center justify-center h-full">
<MessageInput messages={messages} setMessages={setMessages} conversationId={""} />
</div>
);
}
child.tsx
```tsx
"use client";
import { ConversationRole, Message } from "@prisma/client";
import React, { useState } from "react";
type Props = {
messages: Message[];
setMessages: (message: Message[]) => void;
conversationId: string;
};
// The error exists on `setMessages` here
export default function MessageInput({ messages, setMessages, conversationId }: Props) {
const [input, setInput] = useState("");
return (
<div>
<input
onKeyDown={async (e) => {
if (e.key === "Enter") {
setMessages(newMessage);
setInput("");
}
}}
value={input}
onChange={(e) => setInput(e.target.value)}
/>
</div>
);
}
|
Beta Was this translation helpful? Give feedback.
Replies: 14 comments 33 replies
-
Happening with me too.. Request for some pointers |
Beta Was this translation helpful? Give feedback.
-
Have you had any runtime errors due to this? I am have the same error but setting the value to 'any' rather than some variation of '() => void' seems to remove the error. Even without the bandaid fix I have yet to come across any errors in production either. |
Beta Was this translation helpful? Give feedback.
-
You should remove "use client" from child.tsx. A "use client" directive means that component is a boundary between server and client components. Since parent.tsx is already inside the client boundary, everything imported will be client components already. And that includes child.tsx. Why there's this warning? Since it's a boundary, you can potentially use it in a server component. However it's not allowed to have props that can't be serialized in that case. If you import child.tsx and render it inside a server component, there's no way to pass a function as the prop. So this warning also suggests that you should not add "use client" to every client component, but only those boundaries that are directly used in server components. |
Beta Was this translation helpful? Give feedback.
-
I have the same problem. To fix that, I change the function to the arrow function. I don't know why this can fix that problem. |
Beta Was this translation helpful? Give feedback.
-
@shuding Seems like this issue is still there in Removing the "use client" will make it fail with error |
Beta Was this translation helpful? Give feedback.
-
I have the same error with server actions. I want to pass a server action as a prop to a component, as described in the documentation: Edit: I actually only get the lint error, it works at runtime. |
Beta Was this translation helpful? Give feedback.
-
my error was using a before: import { CurrentStep, ImagePicker } from "@/components/ui" after: import { CurrentStep } from "@/components/ui/current-step"
import { ImagePicker } from "@/components/ui/image-picker" |
Beta Was this translation helpful? Give feedback.
-
If you have index.ts file that re-exports your component, you have to set "use client" in index.ts instead of component's file |
Beta Was this translation helpful? Give feedback.
-
I get this when using a version of TS in vscode imported from They are the same version. I use the All in all, I'd say the warning is relatively safe to ignore. |
Beta Was this translation helpful? Give feedback.
-
After investigating what triggers this TypeScript warning, I found that it's based on the following criteria:
These checks seem overly simplistic and don't appear to consider the nuances of crossing server and client boundaries. This could explain why the warning was downgraded from an error. In my opinion, it might be more effective to reframe this as a notice instead of a warning. Something along the lines of: "Just a heads-up: These props are non-serializable. You won't be able to use them in a server component. Make sure to use this component within a client-only context." This approach would offer more clarity and context. As it stands, the current warning feels somewhat cryptic and might confuse developers unfamiliar with the specifics of client/server interactions in React. |
Beta Was this translation helpful? Give feedback.
-
This works for me, replace arrow function with a normal function type Props = {
setMessages(message: Message[]): void;
}; |
Beta Was this translation helpful? Give feedback.
-
Oh my god, reading all these linting problems I wonder if chosing Next.JS was really a good idea... |
Beta Was this translation helpful? Give feedback.
-
I had to remove the |
Beta Was this translation helpful? Give feedback.
-
Bumping, this is the dumbest error. |
Beta Was this translation helpful? Give feedback.
You should remove "use client" from child.tsx.
A "use client" directive means that component is a boundary between server and client components. Since parent.tsx is already inside the client boundary, everything imported will be client components already. And that includes child.tsx.
Why there's this warning? Since it's a boundary, you can potentially use it in a server component. However it's not allowed to have props that can't be serialized in that case. If you import child.tsx and render it inside a server component, there's no way to pass a function as the prop.
So this warning also suggests that you should not add "use client" to every client component, but only those boundaries tha…