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>
)