TypeScript
The Formik source code is written in TypeScript, so you can rest easy that Formik's
types will always be up-to-date. As a mental model, Formik's type signatures are very
similar to React Router 4's <Route>
.
<Formik />
and <Field />
)#
Render props (import * as React from 'react';import { Formik, FormikHelpers, FormikProps, Form, Field, FieldProps,} from 'formik';
interface MyFormValues { firstName: string;}
export const MyApp: React.FC<{}> = () => { const initialValues: MyFormValues = { firstName: '' }; return ( <div> <h1>My Example</h1> <Formik initialValues={initialValues} onSubmit={(values, actions) => { console.log({ values, actions }); alert(JSON.stringify(values, null, 2)); actions.setSubmitting(false); }} > <Form> <label htmlFor="firstName">First Name</label> <Field id="firstName" name="firstName" placeholder="First Name" /> <button type="submit">Submit</button> </Form> </Formik> </div> );};
withFormik()
#
import React from 'react';import * as Yup from 'yup';import { withFormik, FormikProps, FormikErrors, Form, Field } from 'formik';
// Shape of form valuesinterface FormValues { email: string; password: string;}
interface OtherProps { message: string;}
// Aside: You may see InjectedFormikProps<OtherProps, FormValues> instead of what comes below in older code.. InjectedFormikProps was artifact of when Formik only exported a HoC. It is also less flexible as it MUST wrap all props (it passes them through).const InnerForm = (props: OtherProps & FormikProps<FormValues>) => { const { touched, errors, isSubmitting, message } = props; return ( <Form> <h1>{message}</h1> <Field type="email" name="email" /> {touched.email && errors.email && <div>{errors.email}</div>}
<Field type="password" name="password" /> {touched.password && errors.password && <div>{errors.password}</div>}
<button type="submit" disabled={isSubmitting}> Submit </button> </Form> );};
// The type of props MyForm receivesinterface MyFormProps { initialEmail?: string; message: string; // if this passed all the way through you might do this or make a union type}
// Wrap our form with the withFormik HoCconst MyForm = withFormik<MyFormProps, FormValues>({ // Transform outer props into form values mapPropsToValues: props => { return { email: props.initialEmail || '', password: '', }; },
// Add a custom validation function (this can be async too!) validate: (values: FormValues) => { let errors: FormikErrors<FormValues> = {}; if (!values.email) { errors.email = 'Required'; } else if (!isValidEmail(values.email)) { errors.email = 'Invalid email address'; } return errors; },
handleSubmit: values => { // do submitting things },})(InnerForm);
// Use <MyForm /> wherevsconst Basic = () => ( <div> <h1>My App</h1> <p>This can be anywhere in your application</p> <MyForm message="Sign up" /> </div>);
export default Basic;