Bind arguments
Next.js allows you to pass additional arguments to your actions by using the bind
method. This method enables Progressive Enhancement.
next-safe-action exposes a bindArgsSchemas
method that expects an array of schemas for bind arguments.
For example, here we're going to define an onboardUser
action that has userId
and age
as bind arguments and an object with an username
property as the main argument:
src/app/onboard-action.ts
"use server";
import { action } from "@/lib/safe-action";
import { z } from "zod";
const schema = z.object({
username: z.string().min(3).max(30),
});
export const onboardUser = action
.metadata({ actionName: "onboardUser" })
.schema(schema)
// We can pass a named tuple type here, to get named parameters in the final function.
.bindArgsSchemas<[userId: z.ZodString, age: z.ZodNumber]>([
z.string().uuid(),
z.number().min(18).max(150),
])
.define(
async ({
parsedInput: { username },
bindArgsParsedInputs: [userId, age],
}) => {
await new Promise((res) => setTimeout(res, 1000));
return {
message: `Welcome on board, ${username}! (age = ${age}, user id = ${userId})`,
};
}
);
Then, we can use it like this inside a component:
src/app/onboard/page.tsx
"use client";
import { useAction } from "next-safe-action/hooks";
import { onboardUser } from "./onboard-action";
export default function OnboardPage() {
// Here we bind `userId` and `age` to `onboardUser`.
// `boundOnboardUser` will have just `{ username: string }` as its argument, after this `bind` call.
const boundOnboardUser = onboardUser.bind(null, "d3a96f0f-e509-4f2f-b7d0-cdf50f0dc772", 30);
const { execute, result, status, reset } = useAction(boundOnboardUser);
// ...
}