Using shadcn/ui sonner inside server action component
Answered
neon posted this in #help-forum
neonOP
I am not sure if I'm allowed to ask questions about shadcn/ui here, please inform me if I shouldn't, I'll delete this post immediately
This is my code:
As you can see, I have a
This is my code:
import { Textarea } from "@/components/ui/textarea";
import { SendButton } from "./send-button";
import { Toaster } from "./ui/sonner";
import { toast } from "sonner";
export async function SendPage() {
async function send(formData: FormData) {
"use server";
const message = formData.get("message");
// ... some code (make POST request to an API)
toast("Message sent!");
}
return (
<div>
...
<div>
<form action={send}>
<Textarea .../>
<SendButton />
</form>
</div>
<Toaster />
</div>
);
}As you can see, I have a
sonner() function call at the send of the server action (send). But it doesn't seem to work, it gives Error: (0 , sonner__WEBPACK_IMPORTED_MODULE_9__.toast) is not a function error. Are there any workarounds or tricks by which I can run sonner() function when the server action is completed?Answered by Thrianta
Well regardless you can't use
You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
toast in a server component. I believe you will have to use a client component somewhere.You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
"use client"
import {yourServerAction} from "./actions.ts"
<form action={async (formData) => {
const res = await yourServerAction(formData)
if (res.success) toast("success")
}}></form>12 Replies
@neon *I am not sure if I'm allowed to ask questions about shadcn/ui here, please inform me if I shouldn't, I'll delete this post immediately*
This is my code:
tsx
import { Textarea } from "@/components/ui/textarea";
import { SendButton } from "./send-button";
import { Toaster } from "./ui/sonner";
import { toast } from "sonner";
export async function SendPage() {
async function send(formData: FormData) {
"use server";
const message = formData.get("message");
// ... some code (make POST request to an API)
toast("Message sent!");
}
return (
<div>
...
<div>
<form action={send}>
<Textarea .../>
<SendButton />
</form>
</div>
<Toaster />
</div>
);
}
As you can see, I have a `sonner()` function call at the send of the server action (`send`). But it doesn't seem to work, it gives `Error: (0 , sonner__WEBPACK_IMPORTED_MODULE_9__.toast) is not a function` error. Are there any workarounds or tricks by which I can run `sonner()` function when the server action is completed?
Knopper gall
Server actions are not components, they can be 'called with info' but do not share context
You need to use
You need to use
useTransition if you want to do something when the action is fulfilledyou can also await it
@neon can i even use that in server components?
Knopper gall
no useTransition is for client components
you can await the action in server
(or chain .then)
I'm now really confused, are you calling a server action from a server component?
Thrianta
Well regardless you can't use
You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
toast in a server component. I believe you will have to use a client component somewhere.You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
"use client"
import {yourServerAction} from "./actions.ts"
<form action={async (formData) => {
const res = await yourServerAction(formData)
if (res.success) toast("success")
}}></form>Answer
@Knopper gall I'm now really confused, are you calling a server action from a server component?
neonOP
I thought that's how I handle form submissions
Knopper gall
I mean yes, but as @Thrianta said you can't use toast in a server component
@Thrianta Well regardless you can't use `toast` in a server component. I believe you will have to use a client component somewhere.
You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
tsx
"use client"
import {yourServerAction} from "./actions.ts"
<form action={async (formData) => {
const res = await yourServerAction(formData)
if (res.success) toast("success")
}}></form>
neonOP
oh, let me try this then
@Thrianta Well regardless you can't use `toast` in a server component. I believe you will have to use a client component somewhere.
You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
tsx
"use client"
import {yourServerAction} from "./actions.ts"
<form action={async (formData) => {
const res = await yourServerAction(formData)
if (res.success) toast("success")
}}></form>
neonOP
Ah, this works. Tysm!