

Tear-Free Forms with React and Formik
source link: https://www.tuicool.com/articles/hit/VneMJvN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

It’s not often that you write a web app that doesn’t contain at least one form. More often than naught, your entire app is just a series of forms. Each of these forms requires state management, event handlers, and, oftentimes, some sort of client-side data validation. Formik aims to do all of that in a small package and, as they claim, “without the tears”.
⚛️ Recommended course ⤵
Wes Bos' Fullstack Advanced React & GraphQL!Getting Started
To get started with formik
we need to add it to our project via npm
or yarn
:
$ npm install --save formik # or $ yarn add formik
After the dependency has been added, be sure to import it into your project where you’re going to use it. For this article we’re going to use both Formik
and the Form
helper component:
import { Formik, Form } from "formik";
The Form
component is a wrapper for the standard form
element that automatically wires up the onSubmit
handler attached to the Formik
component, saving us even more time.
The Formik Component
The real magic of Formik happens in the Formik
component. This component will be used to wrap your form up and exposes state values and handlers via the render props.
Said component can take properties to set up our default values, validate the submitted values and handle our submission.
Here’s how a Formik
component will look for a basic login form that we’ll be creating later on:
<Formik // Sets up our default values initialValues={{ email: "", password: "" }} // Validates our data validate={values => { const errors = {}; if (!values.email) errors.email = "Required"; if ( !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) ) { errors.email = "You must supply a valid email address"; } if (values.password.length < 8) { errors.password = "Passwords must be at least 8 characters"; } if (values.email === values.password) { errors.password = "Your password shouldn't be the same as your email"; } return errors; }} // Handles our submission onSubmit={(values, { setSubmitting }) => { // This is where you could wire up axios or superagent console.log("Submitted Values:", values); // Simulates the delay of a real request setTimeout(() => setSubmitting(false), 3 * 1000); }} > {props => ( <div>This is where your Form and form elements will go!</div> )} </Formik>
It’s worth nothing, if you’re familiar with object schema validators like
yup
or
joi
you can skip the validate
property and pass in a validationSchema
instead.
The Form Component
As mentioned, the Form
component is a drop-in replacement for a form
element that automagically wires up things like the onSubmit
handler.
Use it to wrap your form’s inputs like you normally would:
<Formik> {props => ( <Form> <label>My Input</label> <input type="text" /> </Form> )} </Formik>
The State of the Inputs
Out of the box, Formik’s render property exposes event handlers to manage changes to your form inputs, whether or not they have been “touched”, their values and any errors.
For the form as a whole, you will be able to tell if the form is in the process of being validated or submitted and an event handler that lets you easily reset the form.
props.values
and props.errors
are objects that have properties that correspond with your form fields.
props.handleChange
and props.handleBlur
can be passed to onChange
and onBlur
properties to track changes and whether or not an input has been “touched”.
This “touched” value comes in handy when you only want to show errors after a user has interacted with an element, instead of at the time of page load (which is preferred IMHO).
props.dirty
gets set to true when the form has been modified by the user.
State values props.isValidating
and props.isSubmitting
let you know what stage of the process the user is in. Perfect for displaying a loader or disabling the form or individual buttons.
Bringing It All Together
Here’s what a simple login form with email and password looks like once it’s been formally Formiked:
<Formik // Sets up our default values initialValues={{ email: "", password: "" }} // Validates our data validate={values => { const errors = {}; if (!values.email) errors.email = "Required"; if ( !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) ) { errors.email = "You must supply a valid email address"; } if (values.password.length < 8) { errors.password = "Passwords must be at least 8 characters"; } if (values.email === values.password) { errors.password = "Your password shouldn't be the same as your email"; } return errors; }} // Handles our submission onSubmit={(values, { setSubmitting }) => { // This is where you could wire up axios or superagent console.log("Submitted Values:", values); // Simulates the delay of a real request setTimeout(() => setSubmitting(false), 3 * 1000); }} > {props => ( <Form> <label htmlFor="email">Email</label> <div> <input name="email" type="email" placeholder="Enter your account email" value={props.values.email} onChange={props.handleChange} onBlur={props.handleBlur} style={{ borderColor: props.errors.email && props.touched.email && "red" }} /> {props.errors.email && props.touched.email && ( <div style={{ color: "red" }}>{props.errors.email}</div> )} </div> <label htmlFor="password">Password</label> <div> <input name="password" type="password" placeholder="Enter your account password" value={props.values.password} onChange={props.handleChange} onBlur={props.handleBlur} style={{ borderColor: props.errors.password && props.touched.password && "red" }} /> {props.errors.password && props.touched.password && ( <div style={{ color: "red" }}>{props.errors.password}</div> )} </div> <input type="submit" value="Submit" disabled={props.isSubmitting} /> <input type="reset" value="Reset" onClick={props.handleReset} disabled={!props.dirty || props.isSubmitting} /> </Form> )} </Formik>
Conclusion
Formik provides a familiar, render prop -based approach to building forms.
Most of the redundant boilerplate and statement management logic you usually end up writing is taken care of nicely while still providing enough power under the hood to do some pretty complex state management on your forms.
If you’d like to give the code from this article a test spin, you can check it out over on CodeSandbox .
Cheers!
Recommend
-
217
Files Permalink Latest commit message Commi...
-
21
How to speed up your React form development with Formik. John Au-Y...
-
10
Forms Handling forms in React Native using Formik and Yup Apr 15, 2021...
-
7
Formik is one of the most popular libraries for building forms. It helps developers do a lot of things with much few lines of code. Some of these things are form state management, validation and error handling. This tutorial will show you thr...
-
9
-
16
-
30
In my last post, I went through building custom components with formik. Today we will build something more practical responsive login/registration page that uses formik components and tailwind styling. In the end, we will add yup validation s...
-
18
-
8
-
4
Dynamic forms with Formik and React JS. 📝 This time I will sho...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK