ReactJS - Formik: Building an Expense Form

Hello there, future React developers! Today, we're going to embark on an exciting journey into the world of form handling in React using a fantastic library called Formik. By the end of this tutorial, you'll be creating sleek and efficient forms like a pro. So, let's dive in!

ReactJS - Formik

What is Formik?

Before we start coding, let's understand what Formik is and why it's such a game-changer in React development.

Formik is a popular library that simplifies form handling in React applications. It takes care of the tedious parts of forms like managing form state, validation, and submission, allowing you to focus on what matters most - your application's logic.

Think of Formik as your personal form assistant. Just like how a good assistant would handle all the paperwork for you, Formik manages all the form-related tasks, leaving you free to focus on the bigger picture.

Setting Up Our Project

First things first, let's set up our project. We'll assume you already have Node.js installed on your computer. If not, go ahead and install it from the official Node.js website.

Open your terminal and run the following commands:

npx create-react-app expense-form-app
cd expense-form-app
npm install formik yup
npm start

These commands create a new React app, install Formik and Yup (a library for form validation), and start the development server.

Creating Our Expense Form

Now that we have our project set up, let's create our expense form. We'll build a simple form that allows users to input an expense description and amount.

Step 1: Basic Form Structure

Let's start by creating a basic form structure. Open your src/App.js file and replace its contents with the following code:

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

function App() {
  return (
    <div className="App">
      <h1>Expense Form</h1>
      <Formik
        initialValues={{ description: '', amount: '' }}
        onSubmit={(values, { setSubmitting }) => {
          setTimeout(() => {
            alert(JSON.stringify(values, null, 2));
            setSubmitting(false);
          }, 400);
        }}
      >
        {({ isSubmitting }) => (
          <Form>
            <div>
              <label htmlFor="description">Description</label>
              <Field type="text" name="description" />
              <ErrorMessage name="description" component="div" />
            </div>
            <div>
              <label htmlFor="amount">Amount</label>
              <Field type="number" name="amount" />
              <ErrorMessage name="amount" component="div" />
            </div>
            <button type="submit" disabled={isSubmitting}>
              Submit
            </button>
          </Form>
        )}
      </Formik>
    </div>
  );
}

export default App;

Let's break down what's happening here:

  1. We import the necessary components from Formik.
  2. We create a Formik component that wraps our form.
  3. We set initialValues for our form fields.
  4. We define an onSubmit function that will handle form submission.
  5. We use Formik's Form, Field, and ErrorMessage components to create our form structure.

Step 2: Adding Validation

Now, let's add some validation to our form. We'll use Yup for this. Update your App.js file as follows:

import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';

const ExpenseSchema = Yup.object().shape({
  description: Yup.string()
    .min(2, 'Too Short!')
    .max(50, 'Too Long!')
    .required('Required'),
  amount: Yup.number()
    .positive('Must be positive')
    .required('Required'),
});

function App() {
  return (
    <div className="App">
      <h1>Expense Form</h1>
      <Formik
        initialValues={{ description: '', amount: '' }}
        validationSchema={ExpenseSchema}
        onSubmit={(values, { setSubmitting }) => {
          setTimeout(() => {
            alert(JSON.stringify(values, null, 2));
            setSubmitting(false);
          }, 400);
        }}
      >
        {({ isSubmitting }) => (
          <Form>
            <div>
              <label htmlFor="description">Description</label>
              <Field type="text" name="description" />
              <ErrorMessage name="description" component="div" />
            </div>
            <div>
              <label htmlFor="amount">Amount</label>
              <Field type="number" name="amount" />
              <ErrorMessage name="amount" component="div" />
            </div>
            <button type="submit" disabled={isSubmitting}>
              Submit
            </button>
          </Form>
        )}
      </Formik>
    </div>
  );
}

export default App;

Here's what we've added:

  1. We import Yup and define a validation schema (ExpenseSchema).
  2. We add the validationSchema prop to our Formik component.

Now our form will validate inputs before submission!

Step 3: Styling Our Form

Let's add some basic styling to make our form look nicer. Create a new file called App.css in your src folder and add the following CSS:

.App {
  font-family: Arial, sans-serif;
  max-width: 400px;
  margin: 0 auto;
  padding: 20px;
}

h1 {
  color: #333;
}

form {
  display: flex;
  flex-direction: column;
}

div {
  margin-bottom: 15px;
}

label {
  margin-bottom: 5px;
  display: block;
}

input {
  width: 100%;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

button {
  background-color: #4CAF50;
  color: white;
  padding: 10px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:disabled {
  background-color: #ddd;
}

.error {
  color: red;
  font-size: 0.8em;
}

Now, update your App.js to import this CSS file:

import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import './App.css';

// ... rest of the code remains the same

Conclusion

Congratulations! You've just built a functional expense form using Formik and React. This is just the beginning of what you can do with Formik. As you continue your React journey, you'll find Formik to be an invaluable tool for handling forms of all complexities.

Remember, practice makes perfect. Try modifying this form, add new fields, or create entirely new forms using what you've learned. The world of React development is vast and exciting, and you're well on your way to becoming a part of it!

Happy coding, and may your forms always validate smoothly! ?

Formik Methods Table

Here's a table of some commonly used Formik methods:

Method Description
handleSubmit Handles form submission
handleChange Handles changes to form fields
handleBlur Handles when a field loses focus
setFieldValue Manually set the value of a field
setFieldTouched Manually set the touched state of a field
validateForm Manually trigger form validation
resetForm Reset the form to its initial values
setErrors Manually set form errors
setStatus Set a top-level status object
setSubmitting Set the submitting state of the form

These methods provide you with fine-grained control over your form's behavior and state. As you become more comfortable with Formik, you'll find yourself reaching for these methods to create more complex and interactive forms.

Credits: Image by storyset