Skip to content

`formAction` builder with new `invalid` control state

Compare
Choose a tag to compare
@MiroslavPetrik MiroslavPetrik released this 03 Feb 19:59
· 84 commits to main since this release

react-form-action now supports a tRPC like API to build actions which share context middleware.
Moreover, the success and failure types were extended with an invalid type, which will appear in the form state alongside validationError which will contain error messages from zod schema validation.

"use server";

import { formAction } from "react-form-action";
import { z } from "zod";
import { cookies } from "next/headers";

const emailSchema = z.object({ email: z.string().email() });

const i18nMiddleware = async () => {
  const { t } = await useTranslation("auth", cookies().get("i18n")?.value);
  // will be added to context
  return { t };
};

// when the email will not be passed or will not be valid, the action
// will automatically fail with result {type: "invalid", validationError: {email: "Invalid"}}
const authAction = formAction(emailSchema)
  .use(i18nMiddleware)
  .use(async ({ ctx: { t } }) =>
    console.log("🎉 context enhanced by previous middlewares 🎉", t)
  )
  .error((error) => {
    if (error instanceof DbError) {
      return error.custom.code;
    } else {
      // unknown error
      // default Next.js error handling (error.js boundary)
      throw error;
    }
  });

export const resendVerifyEmailAction = authAction.run(
  async ({ ctx: { t }, input: { email } }) => {
    // do custom work
    await db.resendVerificationEmail({ email });

    // return translated success message
    return t("verificationEmail.success");
  }
);

export const sendResetPasswordEmail = authAction.run(
  async ({ ctx: { t }, input: { email } }) => {
    // do custom work
    await db.emailPasswordSendPasswordResetEmail({ email });

    // return translated success message
    return t("resetPasswordEmail.success");
  }
);