Next.js Discord

Discord Forum

So am I suppose to create wrapper "client components" for all of my shadcn components???

Answered
Nile perch posted this in #help-forum
Open in Discord
Nile perchOP
I am having a very hard time understanding how best to use server & client components. I just started a brand new nextjs 16 project and have chosen to also use shadcn. First thing I did was add a button component from shadcn and then added it to my app/page.tsx just to make sure it is working. It rendered out fantastic, let me add a onClick handler to it to test interactivity.

And this is where we begin going down the rabbit hole.. by adding an onClick handler you will be met with this error:
Event handlers cannot be passed to Client Component props.
  <button data-slot="button" className=... onClick={function onClick} children=...>
                                                   ^^^^^^^^^^^^^^^^^^
If you need interactivity, consider converting part of this to a Client Component.


Were shadcn components at one time client components by default? Now they are all server components by default?

For something as fundamental as a button, I feel like more times than not you need it to be a client component, unless it's like a submit button for a form or something similar. I really do not understand what to do, should I just add "use client" at the top of the Button component itself and say to hell with it, every button for me will be a client component? Or do I make a thin wrapper ClientButton that essentially just is a pass through to the shadcn Button component?

But then what about all the other components, I have to solve this same issue for all of the others as well... Surely someone else here can point me in a good direction. This seems like the most front-facing problem users would run into, If there is an easy and obvious answer I am not seeing it, somebody please help.
Answered by Pacific herring
hey. you usually see that error when you try to pass a function as prop from a server component down to a client component.

something like this

 
import { Button } from '@/components/ui/button'

function page() {
    function func() {
        console.log('clicked')
    }
    return (
        <div>
            <Button onClick={func}>Click Me</Button>
        </div>
    )
}

export default page


the page component is a server component. when you try to pass a function from a server component to a client component, you'll be met with that error.
a quick fix is to create another component and put your function and button inside.
something like this


'use client'
import { Button } from '@/components/ui/button'

function ClientComponent() {
    function func() {
        console.log('clicked')
    }
    return (
        <Button onClick={func}>Click Me</Button>
    )
}

export default ClientComponent


and then import it into the page component

import ClientComponent from './ClientComponent'

function page() {
    return (
        <ClientComponent />
    )
}

export default page
View full answer

1 Reply

Pacific herring
hey. you usually see that error when you try to pass a function as prop from a server component down to a client component.

something like this

 
import { Button } from '@/components/ui/button'

function page() {
    function func() {
        console.log('clicked')
    }
    return (
        <div>
            <Button onClick={func}>Click Me</Button>
        </div>
    )
}

export default page


the page component is a server component. when you try to pass a function from a server component to a client component, you'll be met with that error.
a quick fix is to create another component and put your function and button inside.
something like this


'use client'
import { Button } from '@/components/ui/button'

function ClientComponent() {
    function func() {
        console.log('clicked')
    }
    return (
        <Button onClick={func}>Click Me</Button>
    )
}

export default ClientComponent


and then import it into the page component

import ClientComponent from './ClientComponent'

function page() {
    return (
        <ClientComponent />
    )
}

export default page
Answer