In my react with typescript project I have a ParentComponent that has a ChildComponent where is a Formik with Yup form that has to be validated as the user types. On the ParentComponent I also have a next button that has to be disabled if there are validation errors as the user types on the form.
This is a code snip of ParentComponent:
const [isFormValid, setIsFormValid] = useState<boolean>(true);
const [isNextButtonDisabled, setIsNextButtonDisabled] = useState<boolean>(false);
useEffect(() => {
if(!isFormValid) {
setIsNextButtonDisabled(true);
}
}, [isFormValid]);
const handleNext = () => {
if (!isFormValid) {
return;
}
goNext();
}
return (
<>
<ChildComponent
setIsFormValid={setIsFormValid}
isFormValid={isFormValid}
/>
<CustomButtonComponent
type="submit"
form="myFormikForm"
isDisabled={isNextButtonDisabled}
/>
</>);
And this is the ChildComponent:
type FormProps = {
isFormValid: boolean;
setIsFormValid: React.Dispatch<React.SetStateAction<boolean>>;
};
export const ChildComponent: React.FC<FormProps> = ({
isFormValid
setIsFormValid,
}) => {
return(
<Formik
initialValues={{email: ''}}
onSubmit={() => {}}
validationSchema={emailValidationSchema}
validateOnChange={true}
validateOnBlur={true}
>
{({ values, errors, handleChange}) => (
<Form
id={"myFormikForm"}
controlId={"myFormikForm"}
value={values.email}
placeholder=""
isInvalid={!!errors.email}
error={errors.email}
onChange={() => {
if(errors.email) {
setIsFormValid(!isFormValid);
}
}}
/>
)}
};
This is how I tried to implement it. The validation of the values inside the form works as expected, the validation messages from emailValidationSchema are correctly displayed under the field as the user types, but it seems like the valid state of the field ‘isFormValid’ doesn’t react the ParentComponent and I can’t disable or enable the button based on the validation state of the Formik form as the user types. How could I achive this?
2
Answers
I guess you have to change tha value inside of
setIsFormValid
.It will keep change the boolean value. Try to set
False
not using negation.I think the correct logic is to set the state of the parent component each time there is a change on the input depending on existance of
errors.email