Reputation: 1111
I'm building form onSubmit functions with useCallback
hooks which will be used in formik
my component using formik might be looks like this,
import { useContactForm } from './useContactForm'
//some functional component
const customSubmit = .... /some submit function
const { initialValues, handleSubmit } = useContactForm(customSubmit);
const formik = useFormik({
initialValues,
onSubmit: handleSubmit //something like this
});
return(
<form onSubmit ={formik.handleSubmit}>
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
/>
<input
id="password"
name="password"
type="password"
onChange={formik.handleChange}
value={formik.values.password}
/>
<button type="submit">Submit</button>
</form>
)
and my useContactForm.ts looks like this. // useContactForm.ts
import { useCallback } from 'react';
interface IContactFormFields {
email: string,
password: string
}
type ISubmitFormType = (value: IContactFormFields, e?: React.FormEvent<HTMLFormElement>) => Promise<void>;
const useContactForm = (submitForm: ISubmitFormType) => {
const handleSubmit = useCallback(
( formFields : IContactFormFields ) => {
return submitForm(formFields).then(() => {
console.log('form submitted');
})
},[]);
const initialValues: IContactFormFields = {
email: "",
password: "",
};
return {
handleSubmit,
initialValues,
}
}
export default useContactForm;
my problem useContactForm
should get custom submit function name submitForm
as a parameter.
then, how my ISubmitFormType
should looks like?
Upvotes: 3
Views: 7173
Reputation: 523
I might be too late for this but I found that your question interesting and I tried to work around it.
Here are my solutions:
useContactForm
hook:// use-contact-form.ts
import { FormikConfig, FormikHelpers } from "formik";
import { useCallback } from "react";
export interface IContactFormFields {
email: string;
password: string;
}
export type ISubmitFormType = FormikConfig<IContactFormFields>["onSubmit"];
const useContactForm = (submitForm: ISubmitFormType) => {
const handleSubmit: ISubmitFormType = useCallback(
async (
formFields: IContactFormFields,
formikBag: FormikHelpers<IContactFormFields>
) => {
const result = await submitForm(formFields, formikBag);
console.log("form submitted");
return result;
},
[]
);
const initialValues: IContactFormFields = {
email: "",
password: "",
};
return {
handleSubmit,
initialValues,
};
};
Notice the
ISubmitFormType
type. We only need to use what was provided by formik themself.
formikHelper
api like usual.// custom-submit-fn.ts
import { ISubmitFormType } from "./use-contact-form";
const customSubmitFn: ISubmitFormType = async (values, formikHelpers) => {
// do something
};
export default customSubmitFn;
// contact-form.tsx
import { useFormik } from "formik";
import { useContactForm } from "./use-contact-form";
import { customSubmitFn } from "./custom-submit-fn";
export default function FunctionalContactForm() {
const { initialValues, handleSubmit } = useContactForm(customSubmitFn);
const formik = useFormik({
initialValues,
onSubmit: handleSubmit, //something like this
});
return (
<form onSubmit={formik.handleSubmit}>
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
/>
<input
id="password"
name="password"
type="password"
onChange={formik.handleChange}
value={formik.values.password}
/>
<button type="submit">Submit</button>
</form>
);
}
Upvotes: 0
Reputation: 644
My 'custom onSubmit' just needed additional data passed to it. There's an answer on Formik's github that worked for me. So if anyone is having trouble passing custom data through the Formik onSubmit or handleSubmit, check this out: https://github.com/jaredpalmer/formik/issues/1900#issuecomment-645034575
Upvotes: 0
Reputation: 24089
How to figure out what the type should be in this case.
From your example, how submitForm is used:
submitForm(formFields).then(() => {
console.log('form submitted');
})
Is it a function?: yes
() => unknown
What goes in: formFields
(formFields) => unknown
What is returned: A Promise
(formFields) => Promise<unknown>
What we have so far:
type ISubmitFormType = (formFields: unknown) => Promise<unknown>
(submitForm: ISubmitFormType) => {...}
Upvotes: 1