Home > database >  How to pass formik props to {children}
How to pass formik props to {children}

Time:11-03

I hope someone out there can help me.

I have created an abstracted reusable form component with Formik, it works really well apart from one issue I can't seem to figure out.

This is my reusable form component

export const Form = (props: any) => {
    const { children, initialValues, onSubmit, schema, formStyles, buttonText, buttonStyles } =
        props;
    const handleSubmit = (values: any, actions: any) => {
        onSubmit(values, actions);
    };

    return (
        <Formik initialValues={initialValues} onSubmit={handleSubmit} validationSchema={schema}>
            {(formikProps: any) => {
                const { handleSubmit, isSubmitting, isValid, dirty } = formikProps;
                return (
                    <form className={formStyles} onSubmit={handleSubmit}>
                        {children}
                        <div className="pt-5">
                            <div className="flex justify-start">
                                <Button
                                    className={buttonStyles}
                                    type="submit"
                                    isLoading={isSubmitting}
                                    disabled={!isValid || !dirty}
                                >
                                    {buttonText}
                                </Button>
                            </div>
                        </div>
                    </form>
                );
            }}
        </Formik>
    );
};

And this is an example form using said component

const ExampleForm = () => {
    return (
        <Form
            initialValues={initialValues}
            onSubmit={(values: any, actions: any) => {
                setTimeout(() => {
                    alert(JSON.stringify(values, null, 2));
                    actions.setSubmitting(false);
                }, 1000);
            }}
            schema={schema}
            buttonText="Submit"
        >
            <div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6">
                <InputField
                    type="text"
                    label="First name"
                    name="firstName"
                    placeholder="First name"
                />
                <InputField type="text" label="Last name" name="lastName" placeholder="Last name" />
                <InputField
                    type="email"
                    label="Email address"
                    name="email"
                    placeholder="Email address"
                    width="col4"
                />
            </div>
        </Form>
    );
};

Currently this works well with the exception of essentially having a hardcoded submit button in the Form Component. I've built it this way because I don't know how to pass the Formik props isSubmitting, isValid, dirty into the {children} prop so that I can access them directly in the example form

Can anyone help with this?

CodePudding user response:

You can pass the formikProps binding with the children. You can try something like this:

export const Form = (props) => {
    return (
        <Formik initialValues={initialValues} onSubmit={handleSubmit} validationSchema={schema}>
            {(formikProps) => (
                <form onSubmit={handleSubmit}>
                    {children(formikProps)}
                </form>
            )}
        </Formik>
    );
};

Then you can access this on the child:

export const ExampleForm = () => (
    <Form>
        {(formikProps) => {
            // you can access the 'formikProps' here
            return (
                <InputField
                    type="email"
                    label="Email address"
                    name="email"
                />
            )
        }}
    </Form>
)
  • Related