0
0
ReactHow-ToBeginner · 4 min read

How to Create Multi Step Form in React: Simple Guide

To create a multi step form in React, use useState to track the current step and conditionally render form parts. Manage form data in state and update it as users progress through steps with buttons triggering step changes.
📐

Syntax

A multi step form in React typically uses useState to hold the current step number and form data. You render different form sections based on the step and provide buttons to move forward or backward.

Key parts:

  • const [step, setStep] = useState(1); tracks which step is active.
  • const [formData, setFormData] = useState({}); stores user inputs.
  • Conditional rendering shows the form fields for the current step.
  • Buttons call setStep(step + 1) or setStep(step - 1) to navigate.
jsx
import React, { useState } from 'react';

function MultiStepForm() {
  const [step, setStep] = useState(1);
  const [formData, setFormData] = useState({});

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

  return (
    <div>
      {step === 1 && <StepOne formData={formData} setFormData={setFormData} />}
      {step === 2 && <StepTwo formData={formData} setFormData={setFormData} />}
      <button disabled={step === 1} onClick={prevStep}>Back</button>
      <button onClick={nextStep}>Next</button>
    </div>
  );
}

function StepOne({ formData, setFormData }) {
  return (
    <input
      type="text"
      placeholder="Name"
      value={formData.name || ''}
      onChange={e => setFormData({ ...formData, name: e.target.value })}
    />
  );
}

function StepTwo({ formData, setFormData }) {
  return (
    <input
      type="email"
      placeholder="Email"
      value={formData.email || ''}
      onChange={e => setFormData({ ...formData, email: e.target.value })}
    />
  );
}
💻

Example

This example shows a simple two-step form where the user enters their name on the first step and email on the second. Navigation buttons let the user move between steps, and the form data is saved in state.

jsx
import React, { useState } from 'react';

export default function MultiStepForm() {
  const [step, setStep] = useState(1);
  const [formData, setFormData] = useState({ name: '', email: '' });

  const nextStep = () => {
    if (step < 2) setStep(step + 1);
  };

  const prevStep = () => {
    if (step > 1) setStep(step - 1);
  };

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

  return (
    <div style={{ maxWidth: '300px', margin: 'auto', fontFamily: 'Arial, sans-serif' }}>
      <h2>Step {step} of 2</h2>
      {step === 1 && (
        <div>
          <label htmlFor="name">Name:</label><br />
          <input
            id="name"
            name="name"
            type="text"
            value={formData.name}
            onChange={handleChange}
            aria-label="Name"
            style={{ width: '100%', padding: '8px', marginTop: '4px' }}
          />
        </div>
      )}
      {step === 2 && (
        <div>
          <label htmlFor="email">Email:</label><br />
          <input
            id="email"
            name="email"
            type="email"
            value={formData.email}
            onChange={handleChange}
            aria-label="Email"
            style={{ width: '100%', padding: '8px', marginTop: '4px' }}
          />
        </div>
      )}
      <div style={{ marginTop: '20px' }}>
        <button onClick={prevStep} disabled={step === 1} aria-disabled={step === 1} style={{ marginRight: '10px' }}>
          Back
        </button>
        {step < 2 ? (
          <button onClick={nextStep}>
            Next
          </button>
        ) : (
          <button onClick={() => alert(JSON.stringify(formData, null, 2))}>
            Submit
          </button>
        )}
      </div>
    </div>
  );
}
Output
Step 1 of 2 [Input box labeled 'Name'] Buttons: Back (disabled), Next After clicking Next: Step 2 of 2 [Input box labeled 'Email'] Buttons: Back, Submit Clicking Submit shows alert with entered name and email.
⚠️

Common Pitfalls

Common mistakes when building multi step forms in React include:

  • Not preserving form data between steps, causing inputs to reset.
  • Using separate state variables for each input instead of one object, making data management harder.
  • Not disabling navigation buttons properly, allowing invalid step numbers.
  • Forgetting to add key props or unique identifiers when rendering steps dynamically.
  • Not handling form submission or validation before moving to the next step.
jsx
/* Wrong: Resets input on step change */
function WrongForm() {
  const [step, setStep] = React.useState(1);
  const [name, setName] = React.useState('');

  return (
    <div>
      {step === 1 && <input value={name} onChange={e => setName(e.target.value)} />}
      {step === 2 && <input placeholder="Email" />}
      <button onClick={() => setStep(step + 1)}>Next</button>
    </div>
  );
}

/* Right: Keeps all data in one state object */
function RightForm() {
  const [step, setStep] = React.useState(1);
  const [formData, setFormData] = React.useState({ name: '', email: '' });

  return (
    <div>
      {step === 1 && (
        <input
          value={formData.name}
          onChange={e => setFormData({ ...formData, name: e.target.value })}
        />
      )}
      {step === 2 && (
        <input
          value={formData.email}
          onChange={e => setFormData({ ...formData, email: e.target.value })}
        />
      )}
      <button onClick={() => setStep(step + 1)}>Next</button>
    </div>
  );
}
📊

Quick Reference

  • Use useState to track current step and form data.
  • Render form sections conditionally based on step.
  • Update form data with a single state object for easier management.
  • Disable navigation buttons when at first or last step.
  • Validate inputs before moving to next step for better user experience.

Key Takeaways

Use React's useState to track the current step and form data in one object.
Render different form parts conditionally based on the step number.
Update form data on input change to preserve user input across steps.
Disable or hide navigation buttons when at the first or last step.
Validate inputs before advancing to ensure data quality.