Refactor form to use useFormik and FormikProvider

Replaced Formik component with useFormik hook and FormikProvider. This change simplifies the form implementation and separates the form's logic and presentation. The form now benefits from more direct access to formik methods and state.
This commit is contained in:
Teriuihi 2024-08-08 21:37:09 +02:00
parent 4dda70effc
commit cde2a01dd9

View File

@ -1,7 +1,7 @@
import React, {useState} from "react"; import React, {useState} from "react";
import './GenericForm.css'; import './GenericForm.css';
import {useNavigate} from 'react-router-dom' import {useNavigate} from 'react-router-dom'
import {ErrorMessage, Field, Form, Formik, FormikValues} from "formik"; import {ErrorMessage, Field, Form, FormikProvider, FormikValues, useFormik} from "formik";
import {Step, UserInput, FormData} from './formInterfaces'; import {Step, UserInput, FormData} from './formInterfaces';
import * as Yup from "yup"; import * as Yup from "yup";
@ -56,30 +56,33 @@ const GenericForm = (formData: FormData) => {
setCurrentStep(current => Math.max(current - 1, 0)) setCurrentStep(current => Math.max(current - 1, 0))
} }
const formik = useFormik({
initialValues: userInput,
validationSchema: spec,
onSubmit: (values) => {
handleSubmit(values);
},
});
const {
touched,
errors,
isValid,
handleChange,
values,
setFieldTouched,
} = formik;
const [prevLength, setPrevLength] = useState(0); const [prevLength, setPrevLength] = useState(0);
return ( return (
<div> <div>
<div> <div>
<h1>{formData.title}</h1> <h1>{formData.title}</h1>
</div> </div>
<div className="container"> <div>
<Formik <FormikProvider value={formik}>
initialValues={userInput} <Form>
validationSchema={spec} <div>
onSubmit={(values: FormikValues) => {
handleSubmit(values);
}}
>
{({
touched,
errors,
isValid,
handleChange,
values,
setFieldTouched
}) => (
<Form>
<div> <div>
<label> <label>
<label> <label>
@ -131,24 +134,30 @@ const GenericForm = (formData: FormData) => {
/> />
) )
} }
</label>
</div>
<div>
<label>
<ErrorMessage name={steps[currentStep].name} component="div"/> <ErrorMessage name={steps[currentStep].name} component="div"/>
</label> </label>
</div> </div>
<button style={{marginLeft: 0}} className="button-outer" type="button" onClick={prev} disabled={currentStep === 0}> <div>
Previous <button style={{marginLeft: 0}} className="button-outer" type="button" onClick={prev} disabled={currentStep === 0}>
</button> Previous
<button className="button-outer" type="button" onClick={next} </button>
hidden={currentStep === (steps.length - 1)} <button className="button-outer" type="button" onClick={next}
disabled={(!touched[steps[currentStep].name] || !!errors[steps[currentStep].name]) || currentStep === (steps.length - 1)}> hidden={currentStep === (steps.length - 1)}
Next disabled={(!touched[steps[currentStep].name] || !!errors[steps[currentStep].name]) || currentStep === (steps.length - 1)}>
</button> Next
<input type="submit" value="Submit" </button>
hidden={currentStep !== (steps.length - 1)} <input type="submit" value="Submit"
disabled={!isValid || currentStep !== (steps.length - 1)} hidden={currentStep !== (steps.length - 1)}
/> disabled={!isValid || currentStep !== (steps.length - 1)}
</Form> />
)} </div>
</Formik> </div>
</Form>
</FormikProvider>
</div> </div>
</div> </div>
); );