setState in child component
Unanswered
Masai Lion posted this in #help-forum
Masai LionOP
I have a parent page that uses 'use client' and has a useState call that passes the setState into a child component, but I'm getting the error
Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it. Both have 'use client' on top, so why is it throwing an error? This only started happening after next 1618 Replies
"I have a parent page that uses 'use client'"
better not mark your page.tsx as "use client"
"Both have 'use client' on top,"
adding "use client" to the top does a little more than just "marking" your component as client component. it is actually also marking your component as the gateway/boundary from server -> client. As such, all components that are marked with "use client" will be checked if they have any functions or unserializable props passed to them. As a result, passing a setState (or any function in that regard) is illegal unless you are trying to make "Server Actions" (which is what the error suggests, by adding "use server").
better not mark your page.tsx as "use client"
"Both have 'use client' on top,"
adding "use client" to the top does a little more than just "marking" your component as client component. it is actually also marking your component as the gateway/boundary from server -> client. As such, all components that are marked with "use client" will be checked if they have any functions or unserializable props passed to them. As a result, passing a setState (or any function in that regard) is illegal unless you are trying to make "Server Actions" (which is what the error suggests, by adding "use server").
Masai LionOP
I want the entire page to be client side rendered because there is state being managed at the top
'use client';
import { useState } from 'react';
export default function Page() {
const [a, setA] = useState('');
return (
<>
<Child a={a} setA={setA} />
<Child2 a={a} />
</>
);
}so for a page like this, how would it work?
@Masai Lion 'use client';
import { useState } from 'react';
export default function Page() {
const [a, setA] = useState('');
return (
<>
<Child a={a} setA={setA} />
<Child2 a={a} />
</>
);
}
so for a page like this, how would it work?
just use "use client" at the top of the tree where you dont pass any function
@Masai Lion I want the entire page to be client side rendered because there is state being managed at the top
yea one way of doing this is by just creating a component like
export default function Page() {
return <PageClient />
}that way you dont use "use client" at page.tsx
Masai LionOP
I see, I guess I can do that
@alfonsüs ardani just use "use client" at the top of the tree where you dont pass any function
use "use client" where you clearly define, "Hey this is the front-line/front-gate where server meets client"
@alfonsüs ardani yea one way of doing this is by just creating a component like
tsx
export default function Page() {
return <PageClient />
}
Masai LionOP
actually nvm I found my issue, it was apparently my layout file that needed use client instead, it just didnt tell me that was the problem and directed me to the page for the error...
Masai LionOP
I dont even use any function calls in the layout, but I am using a ui library
okay, im just saying that usually its not good practice to put "use client" in layout.tsx or page.tsx
Masai LionOP
yeah ik, but I need it to manage state and its a pretty lightweight app
Philippine Crocodile
if the page is entirely client side, it's fine.
i suspect the question is a bit flawed though. you likely want to use context to share state between siblings https://react.dev/reference/react/useContext
i suspect the question is a bit flawed though. you likely want to use context to share state between siblings https://react.dev/reference/react/useContext
@Philippine Crocodile why?
it was shown to have unexpected results in the past
maybe it is more stable now