Error: Type '{ children: Element[]; }' has no properties in common with type 'IntrinsicAttributes & RefAttributes<HTMLFormElement>'

Viewed 4200

I am trying to use Formik in my react application. I have the login component written in ts. For some reason, the Form element inside Formik throws the following error:

Error TS2559 (TS) Type '{ children: Element[]; }' has no properties in common with type 'IntrinsicAttributes & RefAttributes'.

I wonder how I can mitigate this problem. Any solutions?

 <div>
            <Form></Form> // NO ERROR
            <h4>Login</h4>
            <Formik
                initialValues={{
                    username: '',
                    password: ''
                }}
                validationSchema={Yup.object().shape({
                    username: Yup.string().required('Username is required'),
                    password: Yup.string().required('Password is required')
                })}
                onSubmit={({ username, password }, { setStatus, setSubmitting }) => {
                    setStatus();
                    authenticationService.login(username, password)
                        .then(
                            result => {
                                console.log(result);
                                console.log(typeof result);

                                if (result.status == '500') {
                                    setSubmitting(false);
                                    setStatus("Login failed.");

                                } else if (result.status == '200') {
                                    if (result.data["roles"].result.includes('Admin'))
                                        history.push('/admin/courses');

                                    history.push('/courses');
                                }
                            },
                            error => {
                                setSubmitting(false);
                                setStatus(error);
                            }
                        );
                }}
                render={({ errors, status, touched, isSubmitting }) => (
                    <Form> // ERROR!!!
                        <div className="form-group">
                            <label htmlFor="username">Username</label>
                            <Field name="username" type="text" className={'form-control' + (errors.username && touched.username ? ' is-invalid' : '')} />
                            <ErrorMessage name="username" component="div" className="invalid-feedback" />
                        </div>
                        <div className="form-group">
                            <label htmlFor="password">Password</label>
                            <Field name="password" type="password" className={'form-control' + (errors.password && touched.password ? ' is-invalid' : '')} />
                            <ErrorMessage name="password" component="div" className="invalid-feedback" />
                        </div>
                        <div className="form-group">
                            <button type="submit" className="btn btn-primary" disabled={isSubmitting}>Login</button>
                            {isSubmitting && <LoadingSpinner />}
                        </div>
                        {
                            status &&
                            <div className={'alert alert-danger'}>Login failed.</div>
                        }
                    </Form>
                )}
            />

            />

        </div>
2 Answers

This seems to be an issue with formik v2 (released 21 hours ago), I get the same problem with a clean CRA install of formik and it seems to have left out the types allowing <Form /> to have children.

I would recommend downgrading to v1.5.8 for now, I can confirm this will fix your issue.

When using formik I'd also recommend passing value types in, these provide a lot of type safety very easily. You can add type Values = { username: string, password: string } to the top of your file and pass that into the Formik component like <Formik<Values>

For anyone else stuck with this, it still seems to be a problem at least as of Formik v2.0.11 and probably above.

My particular problem was with the use of the withFormik HOC with the Formik's <Form> component, e.g.:


    const MyForm = (props: Props) => {
        const { things, from, the, hoc } = props;
        // some logic
        return (
            <Form>
              <MyCustomFormElements /> 
            </Form
        );
    }
    
    const FormikForm = withFormik({
      mapPropsToValues: (props: OwnProps): OwnForm => {
        return {
          some: 'custom',
          values: 'and things'
        };
      },
      handleSubmit: (values, { props, setSubmitting }) => {
        props.handleSubmit(values, setSubmitting);
      },
      enableReinitialize: true,
      validateOnBlur: true,
      validateOnChange: true,
      validationSchema: (props: OwnProps) => formSchema(props.t),
    })(MyForm);
    
    export default FormikForm;

I had a look at the official example for the withFormik HOC here:

and noticed that, even in the example, they're not using their own <Form /> component. The fix was to replace <Form /> with the standard html <form> like this (and remember to pass the handleSubmit prop to <form>, which is apparently what Formik's <Form /> is failing to do in this case):


    const MyForm = (props: Props) => {
        // notice the explicit use of handleSubmit!!
        const { things, from, the, hoc, handleSubmit } = props;
        // some logic
        return (
            <form onSubmit={handleSubmit}>
              <MyCustomFormElements /> 
            </form>
        );
    }
    
    const FormikForm = withFormik({
      mapPropsToValues: (props: OwnProps): OwnForm => {
        return {
          some: 'custom',
          values: 'and things'
        };
      },
      handleSubmit: (values, { props, setSubmitting }) => {
        props.handleSubmit(values, setSubmitting);
      },
      enableReinitialize: true,
      validateOnBlur: true,
      validateOnChange: true,
      validationSchema: (props: OwnProps) => formSchema(props.t),
    })(MyForm);
    
    export default FormikForm;

Related