react-zod-multistep-form
v0.0.8
Published
A React hook for managing multi-step forms with Zod schema validation and react-hook-form integration. Simplifies navigation between form steps, handles form state, validation, and error management with ease.
Maintainers
Readme
React Zod Multi-Step Form Hook
react-zod-multistep-form is a lightweight React hook designed to simplify the
management of multi-step forms. It integrates react-hook-form with Zod
schema validation to handle form state, validation, and error management across
multiple steps. This hook provides a seamless way to navigate between form steps
while maintaining robust validation and form control.
Features
- Multi-step form management: Easily navigate through multiple form steps with built-in state management.
- Zod schema validation: Integrates
Zodfor schema-based validation at each step to ensure type safety. - React Hook Form integration: Leverages
react-hook-formto handle form state, registration, and validation. - Error handling: Provides detailed error management for each form step, ensuring validation is respected.
- Navigation callbacks: Simple
goToNextStepandgoToPreviousStepfunctions to handle form step transitions while respecting validation. - Field-specific validation: Uses
triggerfromreact-hook-formto validate only the fields in the current step before allowing navigation to the next step.
Installation
npm install react-zod-multistep-formUsage
Here’s how to use the useMultiStepForm hook in your application:
Step 1: Define your form schema using Zod
import { z } from "zod";
const schema = z.object({
name: z.string().min(2, "Name is required"),
age: z.number().min(18, "Must be at least 18"),
});
type FormData = z.infer<typeof schema>;Step 2: Create form step components
import { StepComponent } from "react-zod-multistep-form";
const NameStep: StepComponent<FormData> = ({ register, errors }) => (
<div>
<label>Name</label>
<input {...register("name")} />
{errors.name && <p>{errors.name.message}</p>}
</div>
);
const AgeStep: StepComponent<FormData> = ({ register, errors }) => (
<div>
<label>Age</label>
<input type="number" {...register("age")} />
{errors.age && <p>{errors.age.message}</p>}
</div>
);Step 3: Define your form steps
const steps: Step<FormData>[] = [
{ component: NameStep, fields: ["name"] },
{ component: AgeStep, fields: ["age"] },
];Step 4: Use useMultiStepForm in your form component
import useMultiStepForm from "react-zod-multistep-form";
const MultiStepForm = () => {
const {
CurrentStep,
goToNextStep,
goToPreviousStep,
isFirstStep,
isLastStep,
handleSubmit,
control,
errors,
register,
} = useMultiStepForm<FormData>({
steps,
schema,
initialValues: { name: "", age: 0 },
});
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<form noValidate onSubmit={handleSubmit(onSubmit)}>
<CurrentStep control={control} register={register} errors={errors} />
{!isFirstStep && (
<button type="button" onClick={() => goToPreviousStep()}>
Back
</button>
)}
{!isLastStep && (
<button type="button" onClick={() => goToNextStep()}>
Next
</button>
)}
{isLastStep && <button type="submit">Submit</button>}
</form>
);
};Using trigger for Field-Specific Validation
The useMultiStepForm hook leverages react-hook-form's trigger function to
validate only the fields present in the current step before moving to the next
one. This ensures that each form step only validates the fields it's responsible
for, enhancing performance and making the validation process more intuitive.
In the goToNextStep function, the trigger method is used with the list of
fields from the current step, which ensures that only the fields in that step
are validated before the form transitions to the next step. If validation fails,
the user is not allowed to move to the next step until the errors are resolved.
Example:
const goToNextStep = useCallback(async () => {
const isValid = await trigger(steps[currentStepIndex].fields); // Only validate current step fields
if (!isValid) return;
setCurrentStepIndex((prevStep) =>
prevStep < steps.length - 1 ? prevStep + 1 : prevStep
);
}, [currentStepIndex, steps, trigger]);This approach ensures that each form step only validates the relevant fields, which makes the process more efficient and prevents unnecessary validation across the entire form.
Optional: Separate out Navigation Button logic
type FormNavButtonsProps = {
goToPreviousStep: () => void;
goToNextStep: () => Promise<void>;
isFirstStep: boolean;
isLastStep: boolean;
};
export const FormNavButtons: React.FC<FormNavButtonsProps> = ({
goToPreviousStep,
goToNextStep,
isFirstStep,
isLastStep,
}) => {
return (
<nav>
{!isFirstStep && (
<button type="button" onClick={goToPreviousStep}>
Back
</button>
)}
{!isLastStep && (
<button type="button" onClick={goToNextStep}>
Next
</button>
)}
{isLastStep && <button type="submit">Submit</button>}
</nav>
);
};Step-by-Step Guide
- Define a Zod schema: This schema validates each step of your form.
- Create form step components: Use the
FormStepComponenttype to build form components that handle form fields and errors. - Define form steps: Create an array of objects where each object contains
a
componentandfieldsthat correspond to the Zod schema. - Use the
useMultiStepFormhook: Manage form state, navigation, and validation across steps. - Render the form: Use the hook's
goToNextStepandgoToPreviousStepfunctions to control navigation between steps.
API Reference
Parameters
The useMultiStepForm hook accepts the following parameters:
steps: An array of form steps, each with acomponentand a list offieldsto validate.schema: A Zod schema that defines the structure and validation rules for your form data.initialValues: The initial values for each form field.
The hook also accepts a generic type that can be inferred from your Zod schema, allowing for type-safe form handling.
Return Values
The hook returns an object containing the following properties:
CurrentStep: The current form step component to render.currentStepIndex: The index of the current step.setCurrentStepIndex: A function to manually set the current step index.goToNextStep: Function to move to the next step, ensuring the current step's validation passes.goToPreviousStep: Function to move to the previous step.isFirstStep: Boolean indicating if the current step is the first step.isLastStep: Boolean indicating if the current step is the last step.handleSubmit: The form submission handler fromreact-hook-form.control: Thecontrolobject fromreact-hook-formfor managing form fields.errors: An object containing validation errors for each form field.register: Theregisterfunction fromreact-hook-formfor registering form fields.
License
This project is licensed under the Apache License 2.0.
This package simplifies the process of building multi-step forms with Zod validation in React. If you encounter any issues or have suggestions for improvements, feel free to open an issue or contribute to the repository!
