#Cant use actions in forms

1 messages · Page 1 of 1 (latest)

tiny gate
#

"use server";
import { db } from "@/server/db";
import { stakes } from "@/server/db/schema";
import { eq } from "drizzle-orm";
import { StatusLabelProps } from "../_components/status-label";

export const saveStake = async (e: FormData, id: string) => {
const amount = e.get("amount") as string;
const status = e.get("status") as string;

await db
.update(stakes)
.set({
amount,
stakeStatus: status as StatusLabelProps["status"],
})
.where(eq(stakes.id, id));

return { success: true };
};

this is my file where i've action function I import that function and pass it in client component form like that

      <form
        action={async (e) => {
          await saveStake(e, id);
        }}
      >

but throws error

Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it.

bronze remnantBOT
#

Hi @tiny gate. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

The error message you're seeing is due to the fact that you're trying to pass a server action directly to a client component. In Next.js, server actions need to be marked with the "use server" directive and cannot be defined directly inside a client component.

In your case, you're defining the saveStake function with the "use server" directive, which is correct. However, when you're using this function in your client component, you're wrapping it in another function. This is likely causing the issue, as the outer function is not marked with "use server".

Instead, you should pass the saveStake function directly as the action for your form. If you need to pass additional parameters to the saveStake function, you can create a separate server action function that calls saveStake with the necessary parameters.

Here's an example of how you can do this:

// Server action
"use server";
export async function saveStakeWithId(e: FormData, id: string) {
  await saveStake(e, id);
}

// Client component
<form action={saveStakeWithId} />

In this example, saveStakeWithId is a new server action that calls saveStake with the necessary parameters. You can then pass saveStakeWithId directly as the action for your form.

For more information, you can refer to the Next.js documentation on server actions (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#convention) and this Github issue (https://github.com/vercel/next.js/issues/42408) discussing a similar problem.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: