Create a Multi Step Form using React and the useState Hook

Web Development

In this React Tutorial you will learn how to create a multi step form using React and the useState hook. Learn how to create a multi step form using React and the useState hook. Create a Registration, Sing in and Contact Form in React JS.

Useful links:

Bootstrap: (CSS Framework) https://getbootstrap.com/

React Styled-components https://styled-components.com/

Font Awesome: (Icons for websites) https://fontawesome.com/

Table of content :

  1. Create react project using npx create-react-app
  2. Optimize the React Application
  3. Create React Components
  4. Create a React Button Component
  5. Add props to React Component
  6. Add Bootstrap to React Application
  7. Form input group React Component
  8. Sign up Form React Component
  9. Create Email input in React Form Component
  10. Create Password input in React Form Component
  11. Create React Form Component
  12. Create React Registration Form Component
  13. Create React Contact Form Component
  14. Create Form Next and Prev Button
  15. Add CSS Styling to React App
  16. Create CSS Variables
  17. React useState hook to display Form
  18. Condition React page display using useState hook
  19. Display form title using React useState hook
  20. Display Sign in Form using React useState hook
  21. Display Registration Form using React useState hook
  22. Display Contact Form using React useState hook
  23. Hide the Prev Button on the Sign up form
  24. Create the Form Welcome page
  25. Hide the Prev Button on the Welcome page
  26. Change the text and action of the Next Button to Finish
  27. Change the Page Title Color using React useState hook
  28. Reload the React app using windows.location
  29. Create the form progress bar using React useState hook
  30. Style the Form Progress bar using CSS
  31. Use CSS Variables in React
  32. Save form data in React using useState hook

App.js

The main app.js file will hold the form component. After importing it from the components folder, you can now add it to main div tag witch will return the form component.


import Form from "./components/Form";
import "./App.css";

function App() {
  return (
    <div className="App">
      <Form />
    </div>
  );
}

export default App;

App.css

In the app.css file is where you will add some basic styling for the button component and the progress bar. You do not need to delete enithing from this file just add the CSS

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
:root {
  --purple: #6200ff;
}
.text-purple {
  color: var(--purple);
}
.btn-purple {
  background-color: var(--purple);
  color: #fff;
}
.progress-bar {
  width: 400px;
  height: 10px;
  background-color: white;
  margin-bottom: 50px;
}
.progress-bar div {
  width: 33.3%;
  height: 100%;
  background-color: var(--purple);
}

Components

First you will create a components folder. This will hoste all of you React Components.

Button.js Component

In the Components folder 📁 you can now create your very first react component witch is the button component. The button component will return a button tag with props for className onClick event , the text of the button, and if the button is disabled or nor.

import React from "react";

function Button({ color, text, onClick, isDisabled }) {
  return (
    <button
      className={`btn btn-${color}`}
      onClick={onClick}
      disabled={isDisabled}
    >
      {text}
    </button>
  );
}

export default Button;

FormInputGroup.js component

import React from "react";

function FormInputGroup({ label, type, value, onChange }) {
  return (
    <>
      <div className="col">
        <label htmlFor="input" className="form-label">
          {label}
        </label>
        <input
          type={type}
          value={value}
          onChange={onChange}
          className="form-control"
        />
      </div>
    </>
  );
}

export default FormInputGroup;

Form.js component

import React, { useState } from "react";
import SingUp from "../pages/SingUp";
import PersonalInfo from "../pages/PersonalInfo";
import Address from "../pages/Address";
import Button from "./Button";
import Welcome from "../pages/Welcome";

function Form() {
  const [page, setPage] = useState(0);
  const [formData, setFormData] = useState({
    email: "",
    password: "",
    confirmPassword: "",
    firstName: "",
    lastName: "",
    userName: "",
    street: "",
    city: "",
  });
  const FormTitle = ["Sing Up", "Personal Info", "Address", "Done"];

  const PageDisplay = () => {
    if (page === 0) {
      //   console.log(page);
      return <SingUp formData={formData} setFormData={setFormData} />;
    } else if (page === 1) {
      //   console.log(page);
      return <PersonalInfo formData={formData} setFormData={setFormData} />;
    } else if (page === 2) {
      //   console.log(page);
      return <Address formData={formData} setFormData={setFormData} />;
    } else {
      //   console.log(page);

      return <Welcome formData={formData} />;
    }
  };
  return (
    <main
      className="container shadow p-5 mt-5 rounded-3"
      style={{ maxWidth: 500 }}
    >
      <div className="progress-bar shadow bg-secondary rounded-3">
        <div
          className="div"
          style={{
            width:
              page === 0
                ? "1%"
                : page === 1
                ? "33.3%"
                : page === 2
                ? "66.6%"
                : "100%",
            backgroundColor: page === 3 ? "green" : "var(--purple)",
          }}
        ></div>
      </div>
      <form className="form-container">
        <h1
          className={`"display-2" ${
            page === 3 ? "text-success" : "text-purple"
          }`}
        >
          {FormTitle[page]}
        </h1>
        <div className="text-start">{PageDisplay()}</div>
        <div className="mt-5">
          {page !== 0 && page !== 3 ? (
            <Button
              text="Prev"
              color="dark me-3"
              onClick={(e) => {
                e.preventDefault();
                setPage((currPage) => currPage - 1);
              }}
            />
          ) : null}
          <Button
            text={page !== 3 ? "Next" : "Finish"}
            color={page !== 3 ? "purple" : "success"}
            onClick={(e) => {
              e.preventDefault();
              if (page === FormTitle.length - 1) {
                console.log(formData);
                window.alert("Are you done with the registration");
                window.location.reload();
              } else {
                setPage((currPage) => currPage + 1);
              }
            }}
          />
        </div>
      </form>
    </main>
  );
}

export default Form;

Page / Forms

SingUp.js form

import React from "react";
import FormInputGroup from "../components/FormInputGroup";
function SingUp({ formData, setFormData }) {
  return (
    <>
      <FormInputGroup
        label="Email"
        type="email"
        value={formData.email}
        onChange={(e) => setFormData({ ...formData, email: e.target.value })}
      />
      <FormInputGroup
        label="Password"
        type="password"
        value={formData.password}
        onChange={(e) => setFormData({ ...formData, password: e.target.value })}
      />
      <FormInputGroup
        label="Confirm password"
        type="password"
        value={formData.confirmPassword}
        onChange={(e) =>
          setFormData({ ...formData, confirmPassword: e.target.value })
        }
      />
    </>
  );
}

export default SingUp;

PersonalInfo.js form

import React from "react";
import FormInputGroup from "../components/FormInputGroup";
function PersonalInfo({ formData, setFormData }) {
  return (
    <>
      <FormInputGroup
        label="First name"
        type="text"
        value={formData.firstName}
        onChange={(e) =>
          setFormData({ ...formData, firstName: e.target.value })
        }
      />{" "}
      <FormInputGroup
        label="Last name"
        type="text"
        value={formData.lastName}
        onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}
      />
      <FormInputGroup
        label="User name"
        type="text"
        value={formData.userName}
        onChange={(e) => setFormData({ ...formData, userName: e.target.value })}
      />
    </>
  );
}

export default PersonalInfo;

Address.js

import React from "react";
import FormInputGroup from "../components/FormInputGroup";

function Address({ formData, setFormData }) {
  return (
    <>
      <FormInputGroup
        type="text"
        label="Street"
        value={formData.street}
        onChange={(e) => setFormData({ ...formData, street: e.target.value })}
      />{" "}
      <FormInputGroup
        type="text"
        label="City"
        value={formData.city}
        onChange={(e) => setFormData({ ...formData, city: e.target.value })}
      />
    </>
  );
}

export default Address;

Welcome.js

import React from "react";

function Welcome({ formData }) {
  return (
    <>
      <h4 className="text-center mt-2">Registration was successful for...</h4>
      <div className="card mt-4">
        <h6 className="card-header bg-dark text-white">
          {formData.firstName} {formData.lastName}
        </h6>
        <div className="card-body">
          <ul className="list-group list-group-flush">
            <li className="list-group-item">
              Username:
              <span className="h6 text-success">{formData.userName}</span>
            </li>
            <li className="list-group-item">
              Email: <span className="h6 text-success">{formData.email}</span>
            </li>
          </ul>
        </div>
      </div>
    </>
  );
}

export default Welcome;

Watch the video for more in depth explanation

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.