How does this work???
Answered
Mugger Crocodile posted this in #help-forum
Mugger CrocodileOP
Clearly, this is a server component. But it has an
onClick
event and doesn't throw errors and works? How???Answered by James4u (Tag me if needed)
You are using "use server" directive, it's defining a server action
123 Replies
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
My guess: it logs in browser and you import the navbar from a client component. So it is client
You are using "use server" directive, it's defining a server action
Answer
so it's the same as passing a server action to onClick
no reason to throw an error
I dont see the 'use client' directive anywhere here.
sorry, editied - "use server"
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!
@risky did you know this was a pattern you could do on server comps?
Yeah is a valid thing, but aside from cool demo's it's really not that used
Yeah, I couldnt imagine a real use either :/
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
I don't prefer this pattern btw
Oh me either, but it doesnt mean its not neat!
I personally think the best way for server actions is just action.ts file (ie top level use server files)
ye, agreed. Less ambiguous. I do the same thing, we have gone over how similar our syntax's are for files.
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?Mugger CrocodileOP
But it's not a client component
It's a "server " action tho
@Mugger Crocodile yeah, so what you have is neither of interaction or event listener
it's a server action
Mugger CrocodileOP
Ohhh so next.js automatically detects it's an action and converts it somehow
Then why does this not work?:
hmm must be even more special magic
but i thought it would work
Mugger CrocodileOP
I thought so too
like server action is the only way you can pass a "function" to a client component from server
what error do you see btw?
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
HUH?!
This doesn't work
This doesn't work
But this works?????
how and why
ok that one makes sense, anything after a
return
is dead code (ie never ran)Mugger CrocodileOP
But...
it's a function
like a normal function
not arrow function
that doesnt mean anything
Mugger CrocodileOP
it shouldn't matter where it's declared
its prob deleted in the dead code elimination stage (ie it wont be ran) so it isnt seen by anything
Mugger CrocodileOP
but like
im confused
This should work
i mean in docs i remember them saying to use formAction={} anyway
Mugger CrocodileOP
see this works
well yeah, but it doesn't....
im so confused
i hate this
why js be like that
Mugger CrocodileOP
why?
its just chaos
Mugger CrocodileOP
wdym
why putting functions after return is chaos?
i always do that
it's cleaner
btw are you are on nextjs 14 or 15?
Mugger CrocodileOP
15
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
Mugger CrocodileOP
abhabhahbhabbhu
im confused
so can you try it in v14 :)
Mugger CrocodileOP
Yes, that's what i'm about to do. Which was the latest 14 version?
Mugger CrocodileOP
ty
Mugger CrocodileOP
This doesn't do anything
and this throws an error
very interesting
Mugger CrocodileOP
indeed
maybe onClick being auto converted to a form (i suppose) is a next 15 feature?
Ok so this works
but this still doesn't work (form gets reloaded as action is empty)
my brain stopped braining
🧠 ❌
I think that's sort of updates of Next v15
Mugger CrocodileOP
But this is still v14
button always submits form by default :)
yeah, unless you set type="button"
yeah this is what i meant on https://canary.discord.com/channels/752553802359505017/1300227557811294208/1300442382462091336 (in bad words)
by default any button its type = "submit"
Mugger CrocodileOP
yeah i know that
the question is
why it doesn't recognise the function that is after the return
fun fact, i learnt that from biome (i mean i knew it submited but i thought it was just being funny)
Mugger CrocodileOP
even in next 14
mabye any functions after return statement are being threated as dead code
Mugger CrocodileOP
is that intentional?
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
Mugger CrocodileOP
well yeah, I always write my functions below the return statmenet
oh, sorry was not fully following all of the comments here
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
well, actually original question was answered I guess
we are currently talking about the related ones
nice, btw which msg
lol original question was "how does this work?" - and I answered
now it's time for "why not work!!!"
(i more asking so i can mark thread on a message)
nice
(OP you can still change it if you like)
Mugger CrocodileOP
ok, so here's what we've discussed so far:
-
- 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
-
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
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
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
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.