jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
33.73k stars 2.77k forks source link

Formik "Unable to convert date" that is being handled by Yup schema #3850

Closed RelativeBinary closed 11 months ago

RelativeBinary commented 11 months ago

Bug report

Unable to handle an invalid date onBlur using formik with a yup validation schema

Current Behavior

Setup a basic formik form with a single date field that is validated with a yup schema.

Example of blur behavior not throwing an error on the invalid date (ignore the red input, that is the internals of the input successfully flagging the invalid date) image

The invalid date is caught successfully when submitting image

Expected behavior

That formik's blur catches the typeError correctly and adds that to the errors property

Reproducible example

Unable to reproduce in a codesandbox working with a complicated application that has a custom date input that allows the user to enter inputs like 99/99/2023

/**
 * Component to display report form filters
 * @constructor
 */
const FormikPOC = (): JSX.Element => {
    const handleFooDate = (): void => {
        alert('Success!');
    };

    const initialValues = {
        fooDate: '',
    };

    return (
        <>
                <Formik
                    initialValues={initialValues}
                    validationSchema={
                        Yup.object().shape({
                            fooDate: Yup.date()
                                .typeError('not a valid date')
                                .min('10/10/2000')
                        })
                    }
                    onSubmit={handleFooDate}
                >
                    {(formik) => (
                        <>
                            <Form>
                                    <DatePicker
                                        label={'Foo Date'}
                                        id={'fooDate'}
                                        value={formik.values.fooDate}
                                        onChange={(date) => {
                                            formik.setFieldValue(
                                                'fooDate',
                                                date ? dayjs(date as string).format() : ''
                                            );
                                        }}
                                        onBlur={formik.handleBlur}
                                        onError={(date) => {
                                            // This is the line where formik will throw warnings on blur but not add errors
                                            formik.setFieldValue('fooDate', date);
                                        }}
                                        required={false}
                                        helperText={
                                            formik.errors.fooDate && formik.touched.fooDate
                                                ? formik.errors.fooDate
                                                : 'Date format dd/mm/yyyy'
                                        }
                                        error={!!formik.errors.fooDate && formik.touched.fooDate}
                                    />
                                    <LoadingButton
                                        loading={false}
                                        type={'submit'}
                                        variant={'contained'}
                                        onClick={formik.handleSubmit}
                                    >
                                        Submit
                                    </LoadingButton>
                            </Form>
                            <pre>
                                <br/>ERRORS: {JSON.stringify(formik.errors, null, 2)}
                                <br/>VALUES: {JSON.stringify(formik.values, null, 2)}
                                <br/>DIRTY: {JSON.stringify(formik.dirty, null, 2)}
                                <br/>ISVALID: {JSON.stringify(formik.isValid, null, 2)}
                                <br/>TOUCHED: {JSON.stringify(formik.touched, null, 2)}
                                <br/>
                            </pre>
                        </>
                    )}
                </Formik>
        </>
    );
};

export default FormikPOC;

Suggested solution(s)

Formik handle blur implementation should store an error not log a console warning about the invalid data for the data type in the same way it would if a form field of type number was given a string, I also cannot override this process with setFieldError() method

Additional context

Your environment

Software Version(s)
Formik 2.2.9
React 17.0.2
TypeScript 4.9.5
Browser chrome
npm/Yarn 8.19.4
Operating System Ubuntu 20.04
vennilamahalingam commented 11 months ago

Can I take up this issue ?

vennilamahalingam commented 11 months ago

I am not able to reproduce this issue. I am using the same code as shared by you. On change of the input field, the error message is updated.