Releases: MiroslavPetrik/react-form-action
Releases · MiroslavPetrik/react-form-action
v.2.0.0 ActionContext API
- the action state is provided via the React context by the
<Action>
component and accessible byuseActionContext()
<Form>
is automatically contextualZodFieldError
now is contextual asFieldError
when created with thecreateComponents()
handler.- new
<Pending>
component - better<FormStatus>
which will be deprecated
v.1.3.0@next Action state in Form Context
New API:
- New
createForm
helper to create form using<FormContext>
"use client";
import { createForm } from "react-form-action/client";
// The form renders the classic "render-props Form" and passes the state to FormContext
const { Form } = createForm(action);
- New hook to access the state of the FormContext
import { useFormContext } from "react-form-action/client";
v1.1.0: Use `.format()` on zod error.
v.0.5.0: use .format() on zod error
support for react <18.3 which still uses the useFormState()
from react-dom
v 1.0.1
React 18.3
typefix
- fixes error data in the Form render prop
v0.4.1 bugfix
Fix passing the parseError
of .error(parseError)
v.0.4.0 allow refinements in input
Schemas with refinement are now accepted in .input()
.
Refined schemas, or transformed schemas (with effects) are not augmentable, so only one .input()
call will work for them.
"use server"
import { formAction } from "react-form-action";
export const signUp = formAction
.input(
z
.object({
email: z.string().email(),
password: z.string(),
confirm: z.string(),
})
.refine((data) => data.password === data.confirm, {
message: "Passwords don't match",
path: ["confirm"],
})
) // if using refinement, only one input call is permited, as schema with ZodEffects is not extendable.
.run(async ({ input: { email, password } }) => {
// 🎉 passwords match!
await db.signUp({ email, password });
return "We've sent you an email!";
});
v.0.3.0 Augmentative Input builder & internal form data parsing
"use server";
import { formAction } from "react-form-action";
import { z } from "zod";
const emailAction = formAction.input(z.object({ email: z.string() }));
const emailAndPassswordAction = emailAction.input(
z.object({ password: z.string() })
);
// this is your server action, which accepts FormData
export const signUp = emailAndPassswordAction.run(
async ({ input: { email, password } }) => {
// do something with email and password
await db.signUp(email, password);
}
);
`formAction` builder with new `invalid` control state
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");
}
);