Next.js Discord

Discord Forum

How does this work???

Answered
Mugger Crocodile posted this in #help-forum
Open in Discord
Avatar
Mugger CrocodileOP
Clearly, this is a server component. But it has an onClick event and doesn't throw errors and works? How???
Image
Answered by James4u (Tag me if needed)
You are using "use server" directive, it's defining a server action
View full answer

123 Replies

Avatar
Sun bear
Does your console log in browser or server?

My guess: it logs in browser and you import the navbar from a client component. So it is client
Avatar
You are using "use server" directive, it's defining a server action
Answer
Avatar
so it's the same as passing a server action to onClick
no reason to throw an error
Avatar
I dont see the 'use client' directive anywhere here.
Avatar
sorry, editied - "use server"
Avatar
Sorry I was being an ass I knew what you meant 😅
and while I agree with you... I also didnt know this was a pattern! Its kinda neat!
Avatar
@risky did you know this was a pattern you could do on server comps?
Avatar
Yeah is a valid thing, but aside from cool demo's it's really not that used
Avatar
Yeah, I couldnt imagine a real use either :/
Avatar
Like for an actual app, you would be playing with more checks that would make this chaos code + you can't have loading and other error states
Avatar
I don't prefer this pattern btw
Avatar
Oh me either, but it doesnt mean its not neat!
Avatar
I personally think the best way for server actions is just action.ts file (ie top level use server files)
Avatar
ye, agreed. Less ambiguous. I do the same thing, we have gone over how similar our syntax's are for files.
Avatar
Mugger CrocodileOP
No, it is not client. It is imported from a server component.
Yes, but shouldn't onClick be accessible only via client components?
Yes, I also agree. But my question was different. How is an onClick event possible in a server component?
Avatar
Because server action can pass its function
To client
And thus it invokes the function
Avatar
Mugger CrocodileOP
But it's not a client component
Image
Avatar
It's a "server " action tho
Avatar
@Mugger Crocodile yeah, so what you have is neither of interaction or event listener
it's a server action
Avatar
Mugger CrocodileOP
Ohhh so next.js automatically detects it's an action and converts it somehow
Then why does this not work?:
Image
Image
Avatar
hmm must be even more special magic
but i thought it would work
Avatar
Mugger CrocodileOP
I thought so too
Avatar
like server action is the only way you can pass a "function" to a client component from server
what error do you see btw?
Avatar
Mugger CrocodileOP
 ⨯ Error: Attempted to call signOut() from the server but signOut is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.
even this doesn't work
Image
HUH?!

This doesn't work
Image
But this works?????
Image
how and why
Avatar
ok that one makes sense, anything after a return is dead code (ie never ran)
Avatar
Mugger CrocodileOP
But...
it's a function
like a normal function
not arrow function
Avatar
that doesnt mean anything
Avatar
Mugger CrocodileOP
it shouldn't matter where it's declared
Avatar
its prob deleted in the dead code elimination stage (ie it wont be ran) so it isnt seen by anything
Avatar
Mugger CrocodileOP
but like
im confused
Avatar
This should work
Avatar
i mean in docs i remember them saying to use formAction={} anyway
Avatar
Mugger CrocodileOP
Image
Image
see this works
well yeah, but it doesn't....
im so confused
Avatar
i hate this
why js be like that
Avatar
Mugger CrocodileOP
why?
Avatar
its just chaos
Avatar
Mugger CrocodileOP
wdym
why putting functions after return is chaos?
i always do that
it's cleaner
Avatar
btw are you are on nextjs 14 or 15?
Avatar
Mugger CrocodileOP
15
Avatar
ah yeah, ok if you try this on v14
i feel like there is a chance it may work
one change they did in v15 is not create if not used, so maybe the method assumes code after return is dead
Avatar
Mugger CrocodileOP
abhabhahbhabbhu
im confused
Avatar
so can you try it in v14 :)
Avatar
Mugger CrocodileOP
Yes, that's what i'm about to do. Which was the latest 14 version?
Avatar
Mugger CrocodileOP
ty
Avatar
Mugger CrocodileOP
This doesn't do anything
Image
and this throws an error
Image
Image
Avatar
very interesting
Avatar
Mugger CrocodileOP
indeed
maybe onClick being auto converted to a form (i suppose) is a next 15 feature?
Ok so this works
Image
but this still doesn't work (form gets reloaded as action is empty)
Image
Image
my brain stopped braining
🧠 ❌
I think that's sort of updates of Next v15
Avatar
Mugger CrocodileOP
But this is still v14
Avatar
button always submits form by default :)
Avatar
yeah, unless you set type="button"
Avatar
Avatar
by default any button its type = "submit"
Avatar
Mugger CrocodileOP
yeah i know that
the question is
why it doesn't recognise the function that is after the return
Avatar
fun fact, i learnt that from biome (i mean i knew it submited but i thought it was just being funny)
Avatar
Mugger CrocodileOP
even in next 14
Avatar
mabye any functions after return statement are being threated as dead code
Avatar
Mugger CrocodileOP
is that intentional?
Avatar
thats what i said
and apparently it works for normal function https://canary.discord.com/channels/752553802359505017/1300227557811294208/1300441705576796181 and i personally dont like that
Avatar
Mugger CrocodileOP
well yeah, I always write my functions below the return statmenet
Avatar
oh, sorry was not fully following all of the comments here
Avatar
all good
i just wanted to point to it so op doesnt have to :)
idk even what orig issue is
but i know that server actions have some chaos invoking methods
Avatar
well, actually original question was answered I guess
we are currently talking about the related ones
Avatar
nice, btw which msg
Avatar
lol original question was "how does this work?" - and I answered
now it's time for "why not work!!!"
Avatar
(i more asking so i can mark thread on a message)
Avatar
nice
(OP you can still change it if you like)
Avatar
Mugger CrocodileOP
ok, so here's what we've discussed so far:

- onClick works on a server component if it's passed a server action after next 15
- The server actions has to be declared before the return statement or inline at the onClick callback. Importing them from a seperate actions file won't work.
- My brain stopped working
Avatar
Mugger CrocodileOP
Alright I figured out why putting the action in a seperate file was not working. I accidently imported signOut from 'next-auth/react' instead of '@/auth'
But i'm still confused on why putting a function after the return statement is not working
Avatar
yeah, this is also what I noticed but I ignored as you have the same thing in @/auth
I would recommend you to follow general/best practices that always works
Avatar
Mugger CrocodileOP
But I always wrote my code like that in React - functions after return statement. Suddenly it doesn't work, and only for server actions, as normal functions work.