Multi-step forms with React & TypeScript
Tags: react, typescript, multistep, form
Published: 2020-11-09 10:22:40

## Table of Contents

- [Overview](#overview)
- [What's Changed](#changes)
- [The New API](#new-api)
- [Example Component with TypeScript](#ts-example)

## Overview <a name="overview"></a>

[In my first and latest post](https://dev.to/sametweb/how-to-create-multi-step-forms-in-react-3km4), 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](https://dev.to/t/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? <a name="changes"></a>

| 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.<br />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 <a name="new-api"></a>

| 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 <a name="ts-example"></a>

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.

```javascript
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;
```