Let's face it, forms are really verbose in React. To make matters worse, most form helpers do wayyyy too much magic and often have a significant performance cost associated with them. Formik is a small library that helps you with the 3 most annoying parts:
By colocating all of the above in one place, Formik will keep things organized--making testing, refactoring, and reasoning about your forms a breeze.
I (@jaredpalmer) wrote Formik while building a large internal administrative dashboard with @eonwhite. With around ~30 unique forms, it quickly became obvious that we could benefit by standardizing not just our input components but also the way in which data flowed through our forms.
By now, you might be thinking, "Why didn't you just use Redux-Form?" Good question.
My goal with Formik was to create a scalable, performant, form helper with a minimal API that does the really really annoying stuff, and leaves the rest up to you.
My talk at React Alicante goes much deeper into Formik's motivation and philosophy, introduces the library (by watching me build a mini version of it), and demos how to build a non-trivial form (with arrays, custom inputs, etc.) using the real thing.
Formik started by expanding on this little higher order component by Brent Jackson, some naming conventions from Redux-Form, and (most recently) the render props approach popularized by React-Motion and React-Router 4. Whether you have used any of the above or not, Formik only takes a few minutes to get started with.
You can install Formik with NPM,
Yarn, or a good ol' <script>
via
unpkg.com.
npm install formik --save
or
yarn add formik
Formik is compatible with React v15+ and works with ReactDOM and React Native.
You can also try before you buy with this demo of Formik on CodeSandbox.io
You can play with Formik in your web browser with these live online playgrounds.
Formik keeps track of your form's state and then exposes it plus a few reusable
methods and event handlers (handleChange
, handleBlur
, and handleSubmit
) to
your form via props
. handleChange
and handleBlur
work exactly as
expected--they use a name
or id
attribute to figure out which field to
update.
import React from 'react';import { Formik } from 'formik';const Basic = () => (<div><h1>Anywhere in your app!</h1><FormikinitialValues={{ email: '', password: '' }}validate={values => {const errors = {};if (!values.email) {errors.email = 'Required';} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {errors.email = 'Invalid email address';}return errors;}}onSubmit={(values, { setSubmitting }) => {setTimeout(() => {alert(JSON.stringify(values, null, 2));setSubmitting(false);}, 400);}}>{({values,errors,touched,handleChange,handleBlur,handleSubmit,isSubmitting,/* and other goodies */}) => (<form onSubmit={handleSubmit}><inputtype="email"name="email"onChange={handleChange}onBlur={handleBlur}value={values.email}/>{errors.email && touched.email}<inputtype="password"name="password"onChange={handleChange}onBlur={handleBlur}value={values.password}/>{errors.password && touched.password}<button type="submit" disabled={isSubmitting}>Submit</button></form>)}</Formik></div>);export default Basic;
The code above is very explicit about exactly what Formik is doing. onChange
-> handleChange
, onBlur
-> handleBlur
, and so on. However, to save you time, Formik comes with a few extra components to make life easier and less verbose: <Form />
, <Field />
, and <ErrorMessage />
. They use React context to hook into the parent <Formik />
state/methods.
// Render Propimport React from 'react';import { Formik, Form, Field, ErrorMessage } from 'formik';const Basic = () => (<div><h1>Any place in your app!</h1><FormikinitialValues={{ email: '', password: '' }}validate={values => {const errors = {};if (!values.email) {errors.email = 'Required';} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {errors.email = 'Invalid email address';}return errors;}}onSubmit={(values, { setSubmitting }) => {setTimeout(() => {alert(JSON.stringify(values, null, 2));setSubmitting(false);}, 400);}}>{({ isSubmitting }) => (<Form><Field type="email" name="email" /><ErrorMessage name="email" component="div" /><Field type="password" name="password" /><ErrorMessage name="password" component="div" /><button type="submit" disabled={isSubmitting}>Submit</button></Form>)}</Formik></div>);export default Basic;
Read below for more information...
As you can see above, validation is left up to you. Feel free to write your own
validators or use a 3rd party library. Personally, I use
Yup for object schema validation. It has an
API that's pretty similar to Joi /
React PropTypes but is small enough
for the browser and fast enough for runtime usage. Because I ❤️ Yup sooo
much, Formik has a special config option / prop for Yup called
validationSchema
which will
automatically transform Yup's validation errors into a pretty object whose keys
match values
and
touched
. Anyways, you can
install Yup from npm...
npm install yup --save
or
yarn add yup
The latest Formik news, articles, and resources, sent to your inbox.