Enable Dark Mode!
how-to-create-a-multi-step-form-in-react.jpg
By: Alan Joy

How to Create a Multi-Step Form in React

Technical React

Forms are an essential part of most web applications. The forms are used for registration, checkout, onboarding, profile creation and many other tasks. When these forms contain many fields, it will become hard to display on a single page and can reduce the user experience. A multi-step form solves this problem by providing a better way to organize the form fields. It divides the larger forms into smaller sections. This helps the user to complete one section before moving to the next section. Users can also return to the previous step to update their information if they want. In this blog, we will build a simple multi-step form using react and useState.

1. Create a React Project

First let's create a new react project.

npm create vite@latest react-multi-step-form -template react

cd react-multi-step-form
npm install
npm run dev

2. Manage the Form State

Before building the form, we also need to decide on how to manage the data of the form. A multi-step form is required to need a minimum of two states. A state to store the current step of the form and a state to store the values entered by the user.

Create a file named MultiStepForm.jsx and add this:

import { useState } from "react";
export default function MultiStepForm() {
 const [step, setStep] = useState(1);
 const [formData, setFormData] = useState({
   firstName: "",
   lastName: "",
   email: "",
   phone: "",
 });
 return <div></div>;

3. Create a Function to Update Form Data

Next, we need a function to update the form data. Each input value needs to be saved in the state. Add this function to manage saving the data on each change.

const handleChange = (event) => {
 const { name, value } = event.target;
 setFormData((current) => ({
   ...current,
   [name]: value,
 }));
};

4. Create the Form Steps

Now, we can create the form steps. In this tutorial, we are creating mainly three steps or sections for our multi-step form. The steps are personal information, contact information, and the review step. Update the component with this code.

{step === 1 && (
 <div>
   <h2>Personal Information</h2>
   <input
     name="firstName"
     value={formData.firstName}
     onChange={handleChange}
     placeholder="First name"
   />
   <input
     name="lastName"
     value={formData.lastName}
     onChange={handleChange}
     placeholder="Last name"
   />
 </div>
)}
{step === 2 && (
 <div>
   <h2>Contact Information</h2>
   <input
     name="email"
     value={formData.email}
     onChange={handleChange}
     placeholder="Email address"
   />
   <input
     name="phone"
     value={formData.phone}
     onChange={handleChange}
     placeholder="Phone number"
   />
 </div>
)}
{step === 3 && (
 <div>
   <h2>Review Your Information</h2>
   <p>Name: {formData.firstName} {formData.lastName}</p>
   <p>Email: {formData.email}</p>
   <p>Phone: {formData.phone}</p>
 </div>
)}

5. Add Next and Previous Buttons

Now, we create the buttons for navigation. We are creating two buttons for next and previous navigations. Update our component and add these functions.

const nextStep = () => {
 setStep((current) => current + 1);
};
const previousStep = () => {
 setStep((current) => current - 1);
};

Add these buttons below the form section for the steps.

<div>
 {step > 1 && (
   <button onClick={previousStep}>
     Previous
   </button>
 )}
 {step < 3 ? (
   <button onClick={nextStep}>
     Next
   </button>
 ) : (
   <button onClick={handleSubmit}>
     Submit
   </button>
 )}
</div>

6. Add Form Validation

Next, we can look at validation of the form data. Validation plays a crucial role in validating the imputed data before submitting to the backend or storing it. This helps in finding the missing data and wrong data.

Add a validation function to the component.

const validateStep = () => {
 if (step === 1) {
   return formData.firstName.trim() && formData.lastName.trim();
 }
 if (step === 2) {
   return (
     formData.email.trim() &&
     formData.phone.trim()
   );
 }
 return true;
};

Now, update the nextStep function with this.

const nextStep = () => {
 if (!validateStep()) {
   alert("Please fill in all required fields.");
   return;
 }
 setStep((current) => current + 1);
};

7. Add a Progress Indicator

A progress indicator helps the user to get an idea of where they are in the progress of the form. It shows the form's progress and how many steps remain to complete. Update the component with this code.

<div className="mb-6">
 <p className="mb-2 text-sm text-gray-600">
   Step {step} of 3
 </p>
 <div className="h-2 rounded-full bg-gray-200">
   <div
     className="h-2 rounded-full bg-blue-600"
     style={{ width: `${(step / 3) * 100}%` }}
   />
 </div>
</div>

8. Handle Form Submission

After the user completes the form, it needs to be submitted. So, we can create a function that will handle the form submission.

const handleSubmit = async () => {
 const response = await fetch("/api/users", {
   method: "POST",
   headers: {
     "Content-Type": "application/json",
   },
   body: JSON.stringify(formData),
 });
 if (response.ok) {
   alert("Form submitted successfully!");
 }
};

9. Complete Multi-Step Form Component

import { useState } from "react";
export default function MultiStepForm() {
 const [step, setStep] = useState(1);
 const [formData, setFormData] = useState({
   firstName: "",
   lastName: "",
   email: "",
   phone: "",
 });
 const handleChange = (event) => {
   const { name, value } = event.target;
   setFormData((current) => ({
     ...current,
     [name]: value,
   }));
 };
 const validateStep = () => {
   if (step === 1) {
     return (
       formData.firstName.trim() &&
       formData.lastName.trim()
     );
   }
   if (step === 2) {
     return (
       formData.email.trim() &&
       formData.phone.trim()
     );
   }
   return true;
 };
 const nextStep = () => {
   if (!validateStep()) {
     alert("Please fill in all required fields.");
     return;
   }
   setStep((current) => current + 1);
 };
 const previousStep = () => {
   setStep((current) => current - 1);
 };
 const handleSubmit = () => {
   console.log("Form Data:", formData);
   alert("Form submitted successfully!");
 };
 return (
   <div className="mx-auto max-w-lg rounded-lg border bg-white p-6">
     <div className="mb-6">
       <p className="mb-2 text-sm text-gray-600">
         Step {step} of 3
       </p>
       <div className="h-2 rounded-full bg-gray-200">
         <div
           className="h-2 rounded-full bg-blue-600"
           style={{ width: `${(step / 3) * 100}%` }}
         />
       </div>
     </div>
     {step === 1 && (
       <div className="space-y-4">
         <h2 className="text-lg font-semibold">
           Personal Information
         </h2>
         <input
           name="firstName"
           value={formData.firstName}
           onChange={handleChange}
           placeholder="First name"
           className="w-full rounded border p-2"
         />
         <input
           name="lastName"
           value={formData.lastName}
           onChange={handleChange}
           placeholder="Last name"
           className="w-full rounded border p-2"
         />
       </div>
     )}
     {step === 2 && (
       <div className="space-y-4">
         <h2 className="text-lg font-semibold">
           Contact Information
         </h2>
         <input
           name="email"
           value={formData.email}
           onChange={handleChange}
           placeholder="Email address"
           className="w-full rounded border p-2"
         />
         <input
           name="phone"
           value={formData.phone}
           onChange={handleChange}
           placeholder="Phone number"
           className="w-full rounded border p-2"
         />
       </div>
     )}
     {step === 3 && (
       <div className="space-y-3">
         <h2 className="text-lg font-semibold">
           Review Your Information
         </h2>
         <p>
           Name: {formData.firstName} {formData.lastName}
         </p>
         <p>Email: {formData.email}</p>
         <p>Phone: {formData.phone}</p>
       </div>
     )}
     <div className="mt-6 flex justify-between">
       {step > 1 ? (
         <button
           onClick={previousStep}
           className="rounded border px-4 py-2"
         >
           Previous
         </button>
       ) : (
         <span />
       )}
       {step < 3 ? (
         <button
           onClick={nextStep}
           className="rounded bg-blue-600 px-4 py-2 text-white"
         >
           Next
         </button>
       ) : (
         <button
           onClick={handleSubmit}
           className="rounded bg-green-600 px-4 py-2 text-white"
         >
           Submit
         </button>
       )}
     </div>
   </div>
 );
}

A multi-step form helps in organizing and arranging our large forms into smaller sections. It will help users complete it more easily. In this blog, we have checked how to create a simple multi-step form using React and useState. We have also checked form validation and form submission.

To read more about How to Lazy Load Components in React, refer to our blog How to Lazy Load Components in React.


Frequently Asked Questions

What is a multi-step form in React?

A multi-step form contains different sections, and users can complete this form step by step.

How do I manage form data across multiple steps?

We can use useState to store all form data. We can use this same state for all steps to access data across multiple steps.

How do I validate each step before moving forward?

We can create a validation function to check the form data. We can validate and only proceed to the next step if the validation is successful.

If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



WhatsApp