Reputation: 260
I have formik form build on the react-boostrap form. I have a custom onchange for handling the inputs. The issue is that validation error throw even if there is a value in the form field. Also, If some value is typed then error message is not gone. I guess the validation is not working at all. Please help me on this.
This is the code for react-bootstrap form https://react-bootstrap.github.io/components/forms/#forms-validation-libraries
import React from "react";
import * as yup from "yup";
export default function StepByStepForm() {
const [myForm, setMyForm] = useState({});
const handleInput = (e) => {
const value = e.target.value;
const name = e.target.name;
setMyForm((prev) => ({
...prev,
[name]: value,
}));
};
const form1schema = yup.object({
company_name: yup.string().required(),
});
function Step1Form() {
return (
<Formik validationSchema={form1schema}>
{({
touched,
isValid,
isInvalid,
errors,
handleBlur,
handleChange,
values,
validateForm,
}) => (
<Form noValidate className="formstep1">
<Form.Group controlId="addCompany">
<Form.Label>Company Name*</Form.Label>
<Form.Control
name="company_name"
type="text"
value={myForm.company_name}
onChange={handleInput} // have my custom handling
isInvalid={!!errors.company_name}
/>
<Form.Control.Feedback type="invalid">
{errors.company_name}
</Form.Control.Feedback>
</Form.Group>
<div className="step-progress-btn">
<Button variant="primary" onClick={() => validateForm()}>
Validate
</Button>
</div>
</Form>
)}
</Formik>
);
}
return <div>Step1Form()</div>;
}
Upvotes: 1
Views: 1640
Reputation: 260
The issue was that Formik-Yup needed the onChange={handleChange} to validate
If you have custom or additional functionality on top of handleChange then you need to add the eventlistener on top of handlechange
import React from "react";
import * as yup from "yup";
export default function StepByStepForm() {
const [myForm, setMyForm] = useState({});
const handleInput = (e) => {
const value = e.target.value;
const name = e.target.name;
setMyForm((prev) => ({
...prev,
[name]: value,
}));
};
const form1schema = yup.object({
company_name: yup.string().required(),
});
function Step1Form() {
return (
<Formik validationSchema={form1schema}>
{({
touched,
isValid,
isInvalid,
errors,
handleBlur,
handleChange,
values,
validateForm,
}) => (
<Form noValidate className="formstep1">
<Form.Group controlId="addCompany">
<Form.Label>Company Name*</Form.Label>
<Form.Control
name="company_name"
type="text"
value={myForm.company_name}
onChange={(e) => {
handleChange(e);
handleInput(e);
}}
isInvalid={!!errors.company_name}
/>
<Form.Control.Feedback type="invalid">
{errors.company_name}
</Form.Control.Feedback>
</Form.Group>
<div className="step-progress-btn">
<Button variant="primary" onClick={() => validateForm()}>
Validate
</Button>
</div>
</Form>
)}
</Formik>
);
}
return <div>Step1Form()</div>;
}
Upvotes: 1
Reputation: 2028
Your custom onChange={handleInput}
function never passes the value to Formik.
Formik internally keeps track of your form values, so you don't need to add it using the useState
method like you are now (const [myForm, setMyForm] = useState({});
).
When you add a custom onChange
to your form, you change your component state, while Formik's state never updates, so Yup does not have a value to validate.
If you add this just below your closing </Form>
tag, you will see Formik never reads your form's updated values:
<pre>
{JSON.stringify(
{
touched,
isValid,
isInvalid,
errors,
handleBlur,
handleChange,
values,
validateForm
},
null,
2
)}
</pre>
Upvotes: 1