Next.js Discord

Discord Forum

Does server actions work when used in onClick (as in React's documentation)?

Answered
Standard Schnauzer posted this in #help-forum
Open in Discord
Avatar
Standard SchnauzerOP
I've tried to use server action the same as in https://19.react.dev/reference/rsc/server-actions#creating-a-server-action-from-a-server-component but always get this error Error: Only plain objects, and a few built-ins, can be passed to Server Actions. Classes or null prototypes are not supported.

It works when used in action prop but not in onClick - here's repo with both cases https://dub.sh/JYXdozO
Answered by Standard Schnauzer
mistake in docs confirmed by Ricky from React Team
View full answer

16 Replies

Avatar
it looks like your component is [not declared](https://github.com/arekbartnik/server-actions-test/blob/main/app/page.tsx#L1) as client component. onClick-Events are only useable in client component. So, I guess you want to have it as server component. That's fine and you defined your server action also correctly.

However when it comes to client side interactivity the server action also need to be defined for that. You can see it here: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#client-components
So create a actions.ts and insert your function there.

Like that you are able to use your function in your action-prop as well as in the click event handler (make sure you move your button in another component to mark this other component as client).
Avatar
Standard SchnauzerOP
I know I could define server action in separate file with top level "use server" but React's documentation specify that I should be able to use it inline - I would like to know if it something not implemented in NextJs or if I'm doing something wrong...
Image
Avatar
nextjs behaves a bit different than plain react. nextjs is a fullstack env (backend & frontend). To specifiy specific functions serverside and clientside, you might want to do it they way that I linked here (https://nextjs-forum.com/post/1285150604896899082#message-1285152231145869322 <--- click me) to resolve this error: https://nextjs-forum.com/post/1285150604896899082#message-1285150604896899082
Avatar
Standard SchnauzerOP
Image
Avatar
Standard SchnauzerOP
if this is something that is different about server actions in NextJs than “vanilla” React I would like some confirmation in the NextJs docs 🤔
Avatar
As said:
it looks like your component is not declared as client component.
onClick functions are only executed clientside. So your component need to be clientside. And to use a server action clientside you need a server action that is written for clientside execution.

As said, here is the confirmation from the docs: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#client-components
Image
Avatar
Standard SchnauzerOP
according to the React docs I should be able to use onClick with server actions in server components - so NextJs didn't implement it?
Avatar
instead of onClick={addUser}, use onClick={() => addUser()}
reason: onClick={addUser} is equivalent to onClick={(...manyThings) => addUser(...manyThings)}, this manyThings is not a valid data type for server action as per the error message
only certain data types are allowed to be passed to server actions
calling server action from useEffect, onClick and any client-side events is fully supported and possible.
note that this will require you to use the button in a client component. so you need to make a new client component, add the button there, and use this new client component in the page.

in general it's not possible to drive event handlers in server components like in your code.
Avatar
Standard SchnauzerOP
I understand your explanation but React's documentation gives an example that it should be possible to use server action in onClick without passing it as an anonymous function <- this is the point of my confusion 😅
Avatar
oh you are right, yeah the documentation is wrong there
Avatar
Standard SchnauzerOP
mistake in docs confirmed by Ricky from React Team
Answer