Next.js Functions

 

Working with Forms in NEXT.js: Formik and Yup Integration

In web development, forms are an integral part of most applications, serving as a crucial medium for user interaction and data input. While building forms from scratch can be time-consuming and error-prone, modern frameworks and libraries provide efficient solutions to streamline the process. In this blog, we’ll explore how to work with forms in a NEXT.js application by integrating Formik and Yup. Formik is a popular form library that simplifies form handling, and Yup is a powerful validation library. Together, they offer an elegant and seamless way to manage forms, validate user inputs, and handle form submissions effectively.

Working with Forms in NEXT.js: Formik and Yup Integration

1. Prerequisites

Before diving into the integration of Formik and Yup, make sure you have a basic understanding of the following:

  1. NEXT.js: Familiarity with the fundamentals of building applications with NEXT.js.
  2. React: A basic understanding of React and its components.
  3. JavaScript: Proficiency in JavaScript, as both Formik and Yup are JavaScript-based libraries.

If you’re ready, let’s get started!

2. Setting up a NEXT.js Project

Assuming you already have Node.js installed on your system, we can create a new NEXT.js project using the following commands:

bash
npx create-next-app next-formik-yup-demo
cd next-formik-yup-demo

Once the project is created, you can start the development server:

bash
npm run dev

Now that our NEXT.js project is up and running, let’s proceed with the installation of Formik and Yup.

3. Installing Formik and Yup

To begin, we need to install Formik and Yup into our project. Open a new terminal window and run the following commands:

bash
npm install formik yup

This will install both libraries and add them as dependencies to your project.

4. Creating a Simple Form

Before we dive into Formik and Yup integration, let’s create a simple form using React components. In our example, we’ll build a basic login form with email and password fields. Create a new file LoginForm.js inside the components folder and add the following code:

jsx
import React from 'react';

const LoginForm = () => {
  return (
    <form>
      <div>
        <label htmlFor="email">Email:</label>
        <input type="email" id="email" name="email" />
      </div>
      <div>
        <label htmlFor="password">Password:</label>
        <input type="password" id="password" name="password" />
      </div>
      <button type="submit">Login</button>
    </form>
  );
};

export default LoginForm;

This basic form contains two input fields for email and password, along with a submit button. Next, let’s integrate Formik and Yup to enhance this form with validation and error handling capabilities.

5. Integrating Formik with the Form

To integrate Formik into our form, we need to wrap the form with the Formik component. The Formik component acts as a form manager and handles form state, validation, and submission. Open the LoginForm.js file again and update the code as follows:

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

const LoginForm = () => {
  const initialValues = {
    email: '',
    password: '',
  };

  const validationSchema = Yup.object({
    email: Yup.string().email('Invalid email address').required('Required'),
    password: Yup.string().required('Required'),
  });

  const onSubmit = (values) => {
    console.log(values);
  };

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={onSubmit}
    >
      <Form>
        <div>
          <label htmlFor="email">Email:</label>
          <Field type="email" id="email" name="email" />
          <ErrorMessage name="email" component="div" />
        </div>
        <div>
          <label htmlFor="password">Password:</label>
          <Field type="password" id="password" name="password" />
          <ErrorMessage name="password" component="div" />
        </div>
        <button type="submit">Login</button>
      </Form>
    </Formik>
  );
};

export default LoginForm;

Here’s what we did:

  1. Imported necessary components and libraries from Formik and Yup.
  2. Defined the initial form values (initialValues).
  3. Created a validation schema using Yup, specifying validation rules for each field.
  4. Implemented the onSubmit function to handle form submissions (currently just logging the form values).
  5. Wrapped the form with the Formik component, passing the initialValues, validationSchema, and onSubmit props.
  6. Used the Field component to handle form inputs and the ErrorMessage component to display validation errors if any.

With these changes, our form now has Formik integrated with it, providing form state management and validation capabilities.

6. Form Validation with Yup

Thanks to the integration with Yup, form validation becomes a breeze. We specified the validation rules in the validationSchema object, making it easy to define constraints for each form field. If a user’s input violates any of these constraints, Yup automatically handles the validation and displays appropriate error messages.

For instance, in our example, we have set the following validation rules for the email field:

jsx
email: Yup.string().email('Invalid email address').required('Required'),

This rule enforces that the email field should be a valid email address and cannot be empty. If the user enters an invalid email address or leaves the field blank, Yup will display the error message “Invalid email address” or “Required”, respectively, under the email input field.

7. Form Submission with Formik

Now that we have integrated Formik and validated the form with Yup, let’s handle the form submission. Currently, our onSubmit function only logs the form values, but you can replace this function with an API call to submit the form data to your server.

For example, let’s assume we have an API endpoint to handle user authentication. We’ll use the axios library to make the API call. First, let’s install axios:

bash
npm install axios

Next, we’ll update the onSubmit function to make an API call to our server. In this example, we’ll simulate the API call using setTimeout:

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

const LoginForm = () => {
  const initialValues = {
    email: '',
    password: '',
  };

  const validationSchema = Yup.object({
    email: Yup.string().email('Invalid email address').required('Required'),
    password: Yup.string().required('Required'),
  });

  const onSubmit = (values, { setSubmitting }) => {
    // Simulating an API call
    setTimeout(() => {
      axios.post

Let’s continue with the completion of the onSubmit function and handle the form submission:

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

const LoginForm = () => {
  const initialValues = {
    email: '',
    password: '',
  };

  const validationSchema = Yup.object({
    email: Yup.string().email('Invalid email address').required('Required'),
    password: Yup.string().required('Required'),
  });

  const onSubmit = (values, { setSubmitting }) => {
    // Simulating an API call
    setTimeout(() => {
      axios.post('/api/login', values) // Replace this with your actual API endpoint for user authentication
        .then((response) => {
          console.log('Login successful!');
          console.log(response.data); // The response from the server
        })
        .catch((error) => {
          console.error('Login failed:', error.message);
        })
        .finally(() => {
          setSubmitting(false); // Set submitting to false after the API call is complete
        });
    }, 1000); // Simulate a delay of 1 second to mimic the API call
  };

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={onSubmit}
    >
      <Form>
        <div>
          <label htmlFor="email">Email:</label>
          <Field type="email" id="email" name="email" />
          <ErrorMessage name="email" component="div" />
        </div>
        <div>
          <label htmlFor="password">Password:</label>
          <Field type="password" id="password" name="password" />
          <ErrorMessage name="password" component="div" />
        </div>
        <button type="submit">Login</button>
      </Form>
    </Formik>
  );
};

export default LoginForm;

With the onSubmit function updated, we are now ready to handle form submissions. When the user clicks the “Login” button, Formik will take care of validating the form inputs based on the Yup validation schema. If there are any errors, they will be displayed to the user. If the form passes validation, Formik will call the onSubmit function.

In our example, the onSubmit function simulates an API call using axios.post. Remember to replace the URL with your actual API endpoint for user authentication. In a real-world scenario, this API call would communicate with your server to handle the login process, and you would perform appropriate actions based on the response.

8. Handling Form State

Formik provides access to the form state, such as whether the form is currently being submitted or if any errors exist. You can use this information to conditionally render elements and provide better user feedback. For example, you might want to disable the submit button while the form is being submitted to prevent duplicate submissions.

To disable the submit button while the form is being submitted, you can modify the LoginForm.js file as follows:

jsx
// ... (previous code)

const LoginForm = () => {
  // ... (previous code)

  const onSubmit = (values, { setSubmitting }) => {
    // Simulating an API call
    setTimeout(() => {
      axios.post('/api/login', values)
        .then((response) => {
          console.log('Login successful!');
          console.log(response.data); // The response from the server
        })
        .catch((error) => {
          console.error('Login failed:', error.message);
        })
        .finally(() => {
          setSubmitting(false); // Set submitting to false after the API call is complete
        });
    }, 1000);
  };

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={onSubmit}
    >
      {({ isSubmitting }) => (
        <Form>
          <div>
            <label htmlFor="email">Email:</label>
            <Field type="email" id="email" name="email" />
            <ErrorMessage name="email" component="div" />
          </div>
          <div>
            <label htmlFor="password">Password:</label>
            <Field type="password" id="password" name="password" />
            <ErrorMessage name="password" component="div" />
          </div>
          <button type="submit" disabled={isSubmitting}>
            {isSubmitting ? 'Submitting...' : 'Login'}
          </button>
        </Form>
      )}
    </Formik>
  );
};

export default LoginForm;

By using the isSubmitting prop provided by Formik, we can conditionally disable the submit button when the form is being submitted. The button label will also change to “Submitting…” during the submission process to provide visual feedback to the user.

Conclusion

In this blog, we explored how to streamline form handling in NEXT.js applications using Formik and Yup integration. Formik allowed us to manage form state, validate user inputs, and handle form submissions seamlessly. Yup provided a simple and powerful way to define validation rules for our form fields. Together, they significantly simplified the form development process, saving us time and effort.

Keep in mind that this was just a basic example of how to use Formik and Yup in a NEXT.js project. In real-world applications, forms might require more complexity, such as handling multiple input fields, custom validation logic, or handling form submission errors more gracefully. However, Formik and Yup provide the necessary tools and flexibility to meet these requirements effectively.

I hope this blog helped you understand how to work with forms in NEXT.js using Formik and Yup. Happy coding!

Previously at
Flag Argentina
Brazil
time icon
GMT-3
Accomplished Senior Software Engineer with Next.js expertise. 8 years of total experience. Proficient in React, Python, Node.js, MySQL, React Hooks, and more.