DEV Community

loading...
Cover image for Multi-step forms with React & TypeScript

Multi-step forms with React & TypeScript

Samet Mutevelli
Building stuff
・3 min read

Table of Contents

Overview

In my first and latest post, I introduced my react-step-builder package for creating multi-step front-end interfaces with an example registration form.

Recently, I was working on adding TypeScript support to my project along with some changes to the API of the library. I would like to mention those changes in this post for those who are familiar with the previous version and would like to upgrade to the TypeScript version. If you've never heard of this library, you are encouraged to check out the docs on the GitHub Readme file.

Some of these changes were required to make it work with TypeScript, while some others were purely for clean-up purposes.

What's changed?

v1.1.5 v.2.0.x Reason
props.current N/A No real use case.
props.getState(key) props.getState(key, defaultValue) Before initiating a state value value, getState returns the default value you pass. This change was required for the default types of input.value and input.checked HTML attributes.
For text inputs or textareas, pass an empty string. For checkbox values, pass a boolean value.
props.step N/A Everything under props.step is moved directly under props object. For example: props.step.order is now props.order
props.step.nextStep N/A No real use case.
props.step.prevStep N/A No real use case.

The New API

Property Type Description
props.order number Order number of the current step component
props.title string Title of the current step component
props.progress number Progress of the current step, value between 0 and 1
props.next function Function to move to the next step
props.prev function Function to move to the previous step
props.jump function<step> Function to jump to the given step
props.isFirst function Function to check if the step is the first
props.isLast function Function to check if the step is the last
props.hasPrev function Function to check if the step has any previous step
props.hasNext function Function to check if the step has any next step
props.allSteps Array<{order, title}> Array of all available steps' title and order number
props.state object Combined state value of all steps
props.setState function<key, value> Function to set/update state by key
props.getState function<key, defaultValue> Function to retrieve a state value by key
props.handleChange function<event> onChange event handler for form elements

Example Component with TypeScript

While creating your step components, you may import the type definition StepComponentProps and use it for your component's props. It will give you all the available properties and methods that are available to you in the props object of the step component in your IDE's autocomplete feature.

import React from "react";
import { StepComponentProps } from "react-step-builder";

const Step1 = (props: StepComponentProps) => {
    return (
        <div>
            <input
                name="fname"
                value={props.getState("fname", "")}
                onChange={props.handleChange}
            />
            <input
                name="lname"
                value={props.getState("lname", "")}
                onChange={props.handleChange}
            />
        </div>
    );
};

export default Step1;
Enter fullscreen mode Exit fullscreen mode

Discussion (7)

Collapse
prem1835 profile image
prem1835

I'm making a 2 step form using this library and I'm having confusion in gathering state in one place and sending form data to backend

Collapse
prem1835 profile image
prem1835

Can you quickly explain to me how can I do that please

Collapse
sametweb profile image
Samet Mutevelli Author

Sure. Make sure your form elements have props.handleChange passed as a callback function. The state will be available in the props.state object once the user inputs data in the form elements. Let me know if you still have trouble, I can create an example for you on codesandbox.

Thread Thread
prem1835 profile image
prem1835

I have mailed you on sametmutevellioglu@gmail.com

Collapse
brunogtds profile image
Bruno Gomes Tavares dos Santos

Thanks, this is a very useful package! Is it possible to use this with react hook forms? I'm having some trouble getting the values with props.state with elements wrapped around a Controller component

Collapse
sametweb profile image
Samet Mutevelli Author

react-hook-form registers each input field with a ref object and returns all the fields as an object on form submit. What you can do is, you can create your individual Step components with react-hook-form, and then in your onSubmit method, you can call props.setState(...data) (it saves your data into React Step Builder's global state) and props.next() (it sends you to the next Step). The idea here is, instead of submitting a form with react-step-form, you save its state to React Step Builder's state and move on. react-step-form's state will be your local state inside Step component, React Step Builder's state will be your global state where each and every field from all the steps will be merged.

Collapse
brunogtds profile image
Bruno Gomes Tavares dos Santos

Yeah, I realized I had to use props.setState and it worked out fine! Thanks