Search code examples
reactjsmaterial-uiformikyupformik-material-ui

DatePicker needing 2 clicks to update error, Formik and Yup


I have this Material UI DatePicker:


                    <Grid item xs={12}>
                        <LocalizationProvider dateAdapter={AdapterDayjs}>
                            <DatePicker 
                                label="Date of birth" 
                                format="DD/MM/YYYY" 
                                value = {values.dob}

                                sx={{ width: '50%' }}
                                slotProps={{
                                    textField: {
                                    id: 'dob',
                                    helperText: touched.dob ? errors.dob : "",
                                    error: touched.dob && Boolean(errors.dob),
                                    },
                                    }}
                                    onChange={(value) => { 
                                        setFieldValue('dob', value ? dayjs(value).toDate() : null);
                                        setFieldTouched('dob', true); 
                                    }}
                                />
                        </LocalizationProvider>
                    </Grid>

The problem I have is that my DatePicker only works at the second time.

It says required at the first time instead of saying Date of birth cannot be in the future then at the second time it says Date of birth cannot be in the future.

I always need 2 clicks to change it, if it says Date of birth cannot be in the future and then I change it to yesterday it will still say "Date of birth cannot be in the future", I need to click something else per example the textfield name and click somewhere else and it will update.

If someone can help me it would be great.

Formik:

    const { values, errors, touched, handleBlur, handleChange, handleSubmit, setFieldValue, setFieldTouched } = useFormik({
        initialValues: {
            name: "",
            dob: null,
            email: "",
        },   
        validationSchema: formSchema,
        
    });

Yup:

export const formSchema = yup.object().shape({
    name: yup.string().matches(nameRules, 'Please enter a valid name').max(40).required("Required"),
    dob: yup.date().max(new Date(), 'Date of birth cannot be in the future').required('Required'), 
    email: yup.string().email("Please enter a valid email").required("Required"),
});

I found out that what is making it having to be clicked 2 times to change is the setFieldTouched('dob', true); but if I remove it then I will lose my helperText.

I am expecting for it to change with one click.


Solution

  • I just found out why, the setFieldTouched needs to come first.

    onChange={(value) => { 
      setFieldTouched('dob', true);
      setFieldValue('dob', value ? dayjs(value).toDate() : null);
    }}
    

    instead of:

    onChange={(value) => { 
      setFieldValue('dob', value ? dayjs(value).toDate() : null);
      setFieldTouched('dob', true);
    }}