Announcing Formik 0.11.0

Build forms (with nested state and arrays) in React, without tears.

Each day more and more companies are adopting Formik to handle forms in their React and React Native applications. Our small yet mighty form helper has been downloaded over 200,000 times since July and is now adding ~20-30k more downloads each week. It’s also worth noting that a few of those installs came from teams at Airbnb, OpenTable, and Docker, so that’s pretty darn cool.

Today, I’m excited to announce the release Formik 0.11.0.

tl;dr

What follows is quick summary of the new features. For the full list, be sure to checkout the changelog on GitHub. If you have any issues with this release or need help, hit me up on Twitter, the #formik channel on the Reactiflux Discord channel, or on Spectrum.

"Deep State" updates

Political puns aside, Formik now supports the usage of lodash-like path syntax to wire up inputs to nested parts of your form’s state. What does that mean? Before this, Formik only supported flat state objects out of the box, so nested objects would either need to be flattened or handled with custom inputs. In Formik 0.11, however, you can do this:

import React from 'react'; 
import { Formik, Form, Field } from 'formik';
const App = () => ( 
<div>
<Formik
initialValues={{
social: {
facebook: '',
twitter: ''
}
}}
onSubmit={values => console.log(values)}
render={props => (
<Form>
<Field name="social.facebook" />
<Field name="social.twitter" />
<button type="submit">Submit</button>
</Form>
)}
/>
</div>
);

This should boost developer productivity and cut down on fragile transformation functions you may have littered across your codebase. Path support is available on everywhere you use a field’s name in Formik:

// Regular inputs
<input 
name="social.facebook"
onChange={props.handleChange}
value={values.social.facebook}
/>
// Field component
<Field name="social.facebook" />
// On all imperative field setters
setFieldValue('social.facebook', ...)
setFieldTouched('social.facebook', ...)
setFieldError('social.facebook', ...)
// With arrays! (keep reading...)
<Field name="friends[4].username" />

<FieldArray />

Formik 0.11 ships with a new component purpose-built for forms with lists and array manipulations called <FieldArray>. You pass it a name prop, and then it exposes the following helper methods through render props:

  • push: (obj: any) => void: Add a value to the end of an array
  • swap: (indexA: number, indexB: number) => void: Swap two values in an array
  • move: (from: number, to: number) => void: Move an element in an array to another index
  • insert: (index: number, value: any) => void: Insert an element at a given index into the array
  • unshift: (value: any) => number: Add an element to the beginning of an array and return its length
  • remove<T>(index: number): T | undefined: Remove an element at an index of an array and return it
  • pop<T>(): T | undefined: Remove and return value from the end of the array

Here’s how it looks in practice:

import React from 'react';
import { Formik, Form, Field, FieldArray } from 'formik';

export const InviteFriends = () => (
<div>
<h1>Invite Friends</h1>
<Formik
initialValues={{ friends: ['', '', ''] }}
onSubmit={values => alert(values)}
render={formikProps => (
<Form>
<Field name="email" />
<FieldArray
name="friends"
render={({ remove, push }) => (
<>
{formikProps.values.friends.map((friend, i) => (
<div key={`friend-${i}-${friend}`}>
<Field name={`friends[${i}]`} type="email" />
<button type="button" onClick={() => remove(i)}>
X
</button>
</div>
))}
<button type="button" onClick={() => push('')}>
Add friend
</button>
</>
)}
/>
<button type="submit">Invite Friends</button>
</Form>
)}
/>
</div>
);

FieldArray allows Formik to handle incredibly complex arrays manipulations without sacrificing its validation API. That means you can use Yup and validationSchema or your own validation function with validate and have it work as expected. In the coming weeks, I’ll be writing more about FieldArray as well as some other advanced patterns I’ve found useful.

TypeScript ❤ Formik

As of last week, Formik is now a part of TypeScript’s core user test suite. This ensures that future versions of TypeScript will be fully compatible with Formik’s typings and vice-versa. A big shoutout to Microsoft’s Wesley Wigham and his contributions thus far. He’s already improved Formik’s type inferencing and usage of generics/defaults — which have made Formik 0.11 type errors more intuitive and easier to fix.

What’s coming next?

Docs

The docs site is in the works and it’s going to be awesome. They’ll be runnable examples, a few blueprints for common integrations, a brand new tutorial, and a searchable API reference. Here’s a sneak peak:

Reducer Pattern

By reworking Formik’s internals a little bit, we’ll be able to allow you, the library consumer, to extend Formik’s internal local state with redux-like reducers and middleware.

One more thing…

I’ve started working on an online forms service built on the back of Formik. By adding the forthcoming “Formik Cloud” SDK to your app, you’ll be able to store and manage form submissions and even validation schemas remotely. The goal here isn’t to replace Google Forms or be the next Survey Monkey, but rather to make Formik your go-to interface when it comes to forms.



🖖 I’m Jared Palmer and instead of hunting and gathering, I run a software team called The Palmer Group that builds epic stuff for companies, startups, and governments. I’m passionate about open source and have authored a few libraries such as Formik, Razzle, react-fns, After.js, and Backpack. While my weapon of choice is JavaScript, I’ve been hacking on ReasonML recently and am the organizer of the local NYC meetup.

Twitter: https://twitter.com/jaredpalmer

Newsletter: https://tinyletter.com/jaredpalmer

GitHub: https://github.com/jaredpalmer