Featured Image by James Sutton on Unsplash

Build a multi-step form with no buttons in ReactJS

Nadine Thery
urbanData Analytics
5 min readMar 2, 2021

--

Why would you want to get rid of your next and previous buttons in the first place? Well… because it’s fancy now.

To be honest, this won’t be completely button-less, nor a form 🤔. This is actually a way you can implement a form of any type, whether with Formik, just a plain old form or just gather info and send it to Redux. You name it.

For the sake of simplicity, we will still have one submit button at the end in order to finish the process. But you can apply the same logic if you wish to get rid of that button too.

For this project, we will be using plain React with styled-components library to manage the styling.

I will assume that you have already created your main app structure. We will not dive into Forms in this article, but leave a comment if it’s something you would like to see in this blog 👁️‍🗨️.

You can follow along with the steps in this article in this repository (each step is a branch).

The goal

Our form will have three stages in which we will ask for a name and other nonsense questions with text inputs and radio button inputs. In the last stage, we will have a submit button that will activate only when the previous steps are completed.

Component-translated means that we will have:

  • Form Container that will handle the rendering of other components.
  • Four components one for each stage.

Step 1: Create the structure

First things first, create and export your container and components:

Separated container and components

A basic step component will look kind of like this:

Then, create the form container. From here we will call the steps and control the state in order to call one or another.

I will also add some styling…

Let’s break this down a bit:

  • Components are just basic for now. Put a p inside and export them.
  • Our FormContainer will need to import the useState React Hook in order to manage the rendering of the components.
  • Import all the components for the steps.
  • Create a step state hook inside the FormContainer. We will use this hook to mutate the state and conditionally render the components.

Step 2: Send the info to the parent

In this step, we will create a state in the parent that will receive all the information from the steps and store it while it gets ready to be sent.

We will also prepare “step 0” to send the user name info to the parent.

  • We insert a cute input field that has and id and a value associated with the same prop we want to update in our parent. By putting this id named after the prop, we will be able to reuse our handleChange method.
  • Create a method in the parent that receives the event from the input (whatever the type it is), and extract the id and the value in order to update the state of that prop in our formData object.

Step 3: Waiting for the user to finish writing

Ok, here’s the problem: we have a text input that sends the event to the parent whenever a key is pressed down.

So, before we call a new component we need to be sure that the user has finished writing and Step 0 is complete.

Whenever we need to watch for changes in React JS, we can use the useEffect hook.

This is what we will do:

  1. Create a new state called completedSteps
  2. Set a UseEffect() function that will watch for changes on the formData object.
  3. As soon as formDataupdates, it will evaluate if the step is complete or not. Step 0 only has one input, and we could do this directly. But we can have more than one input to check (we will do that in the next step).
  4. A second UseEffect() will monitor the whole component and call the new component as soon as we detect that the step is completed.
  5. As the user is typing we need to give enough time for the user to finish before showing the new component. We will achieve this by setting a 1000 ms timer ( setTimeOut()) that will start with the first pressed key and reset whenever a key is pressed. As soon as no other key is pressed in a 1000 ms interval, the new component will render.

Step 4: Enter inputs and step completion validation for the other steps

From here on you can add as many inputs and steps as you wish. Ideally, you should also add a way to go back and change info, or maybe a swipe animation between steps…?

Define your submit process accordingly and you are all set.

Check out the full repository for the full example and play around with it. Also, take a look at step1.js to see how we manage two different inputs in the same step.

For any questions, please feel free to leave a comment.

Peace & Code

Nadine.

--

--

Nadine Thery
urbanData Analytics

Frontend Developer 👩🏻‍💻, videogamer 🎮, boardgamer 🎲, plant-lady 🌿, mother-of-cat-and-dogs 🐱🐶🐶, environment-concerned🌎, youtuber, ocassional podcaster