DEV Community

DCT Technology Pvt. Ltd.
DCT Technology Pvt. Ltd.

Posted on

Creating a Multi-Step Form in React with Validation

Ever started filling out a long form and clicked away halfway through? Yeah, we’ve all been there.

Long forms are conversion killers — unless you break them down into multi-step forms that feel more digestible and less overwhelming.

In this post, I’ll walk you through how to build a multi-step form in React using functional components, hooks, and validation — the right way.

You’ll walk away with:

  • A complete working form example

  • Modular structure tips

  • Field validation logic

  • UI/UX ideas to keep users engaged

Let’s get building. 🛠️

Image description

🧱 Why Multi-Step Forms Matter?

  • They reduce cognitive load.

  • They feel quicker, even when they’re not.

  • You can guide users through a journey (like onboarding, checkout, lead capture, etc.).

  • You can add validation at each step so users don’t get errors at the end.


⚙️ What We’re Building

A basic 3-step form:

  1. User Info (Name, Email)
  2. Address Info (City, Country)
  3. Review & Submit

Each step:

  • Has validation
  • Uses React Hook Form (or custom logic)
  • Includes navigation buttons

👉 Here’s a live CodeSandbox demo you can fork


🛠️ Setup Your React Project

npx create-react-app multi-step-form
cd multi-step-form
npm install
Enter fullscreen mode Exit fullscreen mode

Install required dependencies:

npm install react-hook-form
Enter fullscreen mode Exit fullscreen mode

📦 Folder Structure

src/
│
├── components/
│   ├── Step1.jsx
│   ├── Step2.jsx
│   ├── Step3.jsx
│   └── MultiStepForm.jsx
│
└── App.jsx
Enter fullscreen mode Exit fullscreen mode

✨ Multi-Step Form Logic (MultiStepForm.jsx)

import React, { useState } from "react";
import Step1 from "./Step1";
import Step2 from "./Step2";
import Step3 from "./Step3";

const MultiStepForm = () => {
  const [step, setStep] = useState(1);
  const [formData, setFormData] = useState({
    name: "",
    email: "",
    city: "",
    country: "",
  });

  const nextStep = () => setStep(prev => prev + 1);
  const prevStep = () => setStep(prev => prev - 1);

  const handleChange = (input) => (e) => {
    setFormData({ ...formData, [input]: e.target.value });
  };

  switch (step) {
    case 1:
      return <Step1 nextStep={nextStep} handleChange={handleChange} values={formData} />;
    case 2:
      return <Step2 nextStep={nextStep} prevStep={prevStep} handleChange={handleChange} values={formData} />;
    case 3:
      return <Step3 prevStep={prevStep} values={formData} />;
    default:
      return null;
  }
};

export default MultiStepForm;
Enter fullscreen mode Exit fullscreen mode

🧩 Step Components

Step1.jsx

import React from "react";

const Step1 = ({ nextStep, handleChange, values }) => {
  const continueStep = (e) => {
    e.preventDefault();
    if (values.name && values.email) {
      nextStep();
    } else {
      alert("All fields required");
    }
  };

  return (
    <div>
      <h2>User Info</h2>
      <input type="text" placeholder="Name" onChange={handleChange("name")} value={values.name} />
      <input type="email" placeholder="Email" onChange={handleChange("email")} value={values.email} />
      <button onClick={continueStep}>Next</button>
    </div>
  );
};

export default Step1;
Enter fullscreen mode Exit fullscreen mode

Build similar structure for Step2.jsx and Step3.jsx. Add validation checks in each.


🎨 UI/UX Tips to Increase Engagement

  • Add a progress bar or step indicators.
  • Use animation transitions when switching steps. Try Framer Motion.
  • Use emojis or icons to keep it friendly.
  • Include live validation with helpful tooltips.
  • Add final confirmation before submission.

🔐 Form Validation

You can build your own checks, or use:

Example with react-hook-form:

import { useForm } from "react-hook-form";

const { register, handleSubmit, errors } = useForm();
Enter fullscreen mode Exit fullscreen mode

🧠 Bonus: Save Progress in LocalStorage

Want users to come back later?

useEffect(() => {
  localStorage.setItem("formData", JSON.stringify(formData));
}, [formData]);

useEffect(() => {
  const saved = JSON.parse(localStorage.getItem("formData"));
  if (saved) setFormData(saved);
}, []);
Enter fullscreen mode Exit fullscreen mode

🎁 Ready to Take It Further?

Here are some challenges you can try:

  • Add field-level validation using Yup
  • Connect to backend (e.g. with Firebase or Express API)
  • Add dynamic fields (like repeatable work experience)
  • Add animations with Framer Motion

✅ Multi-step forms don’t have to be complicated. With modular components and clean state management, they’re easy to scale and great for UX.


💬 Drop a comment if you want a version using TypeScript, Material UI, or Framer Motion. I’d be happy to share!

👉 Follow **[DCT Technology] for more web development insights, design tips, SEO hacks, and IT consulting knowledge.


#ReactJS #WebDevelopment #UXDesign #JavaScript #Forms #DevCommunity #FrontendDev #ReactHookForm #Validation #DCTTechnology #UIUX #CodingTips #CleanCode #Programmer

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

Join the Runner H "AI Agent Prompting" Challenge: $10,000 in Prizes for 20 Winners!

Runner H is the AI agent you can delegate all your boring and repetitive tasks to - an autonomous agent that can use any tools you give it and complete full tasks from a single prompt.

Check out the challenge

DEV is bringing live events to the community. Dismiss if you're not interested. ❤️