I'm working on implementation of a multi step form with react-hook-form
and my problem is that input fields do not get reinitialized with the form data when I return to the previous page.
I'm using <FormProvider />
ponent from react-hook-form
to inject the form data into the pages and my input
ponents are registered with register
method from useFormContext()
hook
const CreateAccount = () => {
const [currentStep, setCurrentStep] = useState(0);
const methods = useForm<FormData>({
mode: "onChange",
});
const onSubmit = (data) => console.log(data);
const handleNextStep = () => {
if (currentStep >= 5) return;
setCurrentStep(currentStep + 1);
};
const handlePreviousStep = () => {
if (currentStep <= 0) return;
setCurrentStep(currentStep - 1);
};
const renderContent = () => ({
[RegistrationSteps.UsernameEmail]: <UsernameEmail handleNextStep={handleNextStep} handlePreviousStep={handlePreviousStep} />,
[RegistrationSteps.Password]: <CreatePassword handleNextStep={handleNextStep} handlePreviousStep={handlePreviousStep} />,
});
return (
<Container maxWidth="sm">
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
{renderContent()[currentStep]}
</form>
</FormProvider>
</Container>
);
};
export default CreateAccount;
Here is what the input fields look like
const {
register
} = useFormContext();
<TextField
label="Email"
{...register("email")}
/>
Even though the form still holds the data in its state, it does not populate into corresponding fields when I switch back and forth between the form pages.
I'm working on implementation of a multi step form with react-hook-form
and my problem is that input fields do not get reinitialized with the form data when I return to the previous page.
I'm using <FormProvider />
ponent from react-hook-form
to inject the form data into the pages and my input
ponents are registered with register
method from useFormContext()
hook
const CreateAccount = () => {
const [currentStep, setCurrentStep] = useState(0);
const methods = useForm<FormData>({
mode: "onChange",
});
const onSubmit = (data) => console.log(data);
const handleNextStep = () => {
if (currentStep >= 5) return;
setCurrentStep(currentStep + 1);
};
const handlePreviousStep = () => {
if (currentStep <= 0) return;
setCurrentStep(currentStep - 1);
};
const renderContent = () => ({
[RegistrationSteps.UsernameEmail]: <UsernameEmail handleNextStep={handleNextStep} handlePreviousStep={handlePreviousStep} />,
[RegistrationSteps.Password]: <CreatePassword handleNextStep={handleNextStep} handlePreviousStep={handlePreviousStep} />,
});
return (
<Container maxWidth="sm">
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
{renderContent()[currentStep]}
</form>
</FormProvider>
</Container>
);
};
export default CreateAccount;
Here is what the input fields look like
const {
register
} = useFormContext();
<TextField
label="Email"
{...register("email")}
/>
Even though the form still holds the data in its state, it does not populate into corresponding fields when I switch back and forth between the form pages.
Share Improve this question asked Jul 21, 2021 at 13:58 Oleksandr FominOleksandr Fomin 2,3868 gold badges30 silver badges51 bronze badges1 Answer
Reset to default 4Instead of a single form at a global level, I remend creating each ponent in your step as a form with its own instance of useForm()
and wrapping steps in a state provider to store data across different steps. That way, you can assign values to the step forms from the respective state using defaultValues
option of useForm
on initialization.
You can check out this for the basic architecture that I'm trying to explain.
defaultValues in useForm