# Build a React + Redux App with TypeScript, Redux Form, and Jest

### Overview

There are many separate articles on how to use TypeScript with Redux, Redux Form, and how to test Redux apps. This article combines all the knowledge into a single location to prevent you from needing to search for them all individually.

Today we will combine all the major topics of React into a single application so that users can learn everything together in one place.

### Objectives

#### Part 1

* Creating a React project using TypeScript
    
* Installing the plugins
    
* Folder Structure
    
* Creating Redux Form (pages)
    
* Creating Redux and persisting state
    
* Storing the form data in the redux store
    

#### Part 2

* Installing the plugins needed for Jest
    
* Setting the Jest environment
    
* Writing test case for Redux form
    
* Writing test case for the Redux action and reducers
    

### 1\. Creating a react project

Let’s begin by creating a React app using the command below

```bash
create-react-app reduxform-jest --typescript
cd reduxform-jest
npm start
```

### 2\. Installing the plugins

We will install the list of plugins needed for this application.

* [redux-form](https://www.npmjs.com/package/redux-form)
    
* [redux](https://www.npmjs.com/package/redux)
    
* [react-router-dom](https://www.npmjs.com/package/react-router-dom)
    
* [react-stepper-horizontal](https://www.npmjs.com/package/react-stepper-horizontal)
    
* [reactstrap](https://www.npmjs.com/package/reactstrap)
    
* [bootstrap](http://npm%20i%20bootstrap)
    
* [redux-thunk](https://www.npmjs.com/package/redux-thunk)
    
* [redux-persist](https://www.npmjs.com/package/redux-persist)
    

Since we are using TypeScript, we have to install the type packages for the plugins as well. Once the plugins and their types are installed, it’s time to create the folder structure for the application

### 3\. Folder structure

Inside **src** folder create the directories:

* components
    
* lib
    
* pages
    
* redux
    
* styles
    
* types
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056773004/60de6a33-997f-44e6-a338-fac45c5abd6a.png align="left")

### 4\. Creating Redux Form (Pages)

Inside **pages** folders create another folder named `**Users**` and then add the below files inside the **Users** folder:

* User.tsx
    
* Form.tsx
    
* PersonalDetailForm.tsx
    
* AccountDetailForm.tsx
    
* AddUser.d.ts
    
* validate.ts
    
* index.ts
    

Once these files are created, we will create the form named `user`.

#### User.tsx

In the User.tsx file, we will handle the form submit function as well as the Redux action call.

User.tsx

In the above code, we have used a functional component instead of a class component so we can use state hooks for button loading.

You might notice that we have imported the `**Form**` component which we are going to handle next.

#### Form.tsx

In Form.tsx, we will use the `react-stepper` which will give a wizard effect for the pages. We also need to import the **PersonalDetailForm** Component and **AccountDetailForm** Component.

Form.tsx

In the above code, we have used the state hooks to handle the current page as well as the `Stepper` component to show the wizard page effect.

Based on the page select the state hook gets updated in `nextPage()` and `previousPage()`.

#### PersonalDetailForm.tsx

In `PersonalDetailForm` we will create the form fields for Name, DOB, Age, Gender, Mobile Number and Address.

In the above code, you might have noticed the components **ReduxFormInput** and **ReduxFormSelect** which are the custom components which we will see soon.

> There would be many errors showing since we have not created ReduxFormInput, ReduxFormSelect, and validate.ts yet. Don’t be panic we will add it in a couple of minutes :)

#### AccountDetailForm.tsx

In AccountDetailForm we will have 2 input fields and a textarea field to get the account number, bank name, and bank address and two buttons previous (go to personal details tab) and save (To save the form).

Now we have created the AccountDetailForm. In both the forms, you might notice some common things like below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056775593/5f22c3a1-d33b-4457-b0ad-238a1987f1c0.png align="left")

Since we are using a single form to handle all the inputs we have used the form name to be `user` (common across the page). You could see the `destroyOnUnmount` and `forceUnregisterOnUnmount` which is used to handle the form values to exist when we move to different pages in the wizard.

Now we will create the `**ReduxFormInput**` and `**ReduxFormSelect**` components.

Inside components folder created two new folders **ReduxFormInput** and **ReduxFormSelect** and create files with the same name as well as **index.ts** file in each folder.

#### ReduxFormInput.tsx

Inside the ReduxFormInput file add the below code

And import the **ReduxFormInput** in **index.ts** and export the file.

#### ReduxFormSelect.tsx

Inside the ReduxFormSelect add the below code

And import the **ReduxFormSelect** in **index.ts** and export the file.

Now we have created the **ReduxFormInput** and **ReduxFormSelect** components. Next we will create the validate file.

#### validate.ts

Since we are going to validate the form, it is a good practice to have the validation in a separate file rather than writing the inline validation and making the code clumsy.

We have added the validate options for the form. You could see some errors in the PersonalDetailForm and AccountDetailForm from `normalize` and `datas`.

We will now add files that we assumed existed previously.

In the **config** folder create a file named **constants.ts**

In **lib** folder create a file named **normalize.ts**

Add the user types in **User** -&gt; **AddUser.d.ts**

In `User` the folder go to index.ts and import User.tsx and export the same as below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056777923/b984b8a2-2af1-4e3a-8eab-f7bd7e2340e6.png align="left")

Now go to App.tsx and remove the default code and add the below code.

Now go to **User.tsx** and hide the dispatch call like below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056779713/550fa785-14c7-4daa-bbe3-ede24a2e6802.png align="left")

Since we are going to check whether the design is working or not we don’t need the dispatch calls which we will use later.

### **4\. Creating Redux and persist**

Now go to the **redux** folder and create another folder named **reducers. I**nside **reducers** folder create a file named **index.tsx** and add the below code

Then create another folder named **store** inside **redux** folder and created a file named **index.tsx** and add the below code.

Here we are handling the Redux store (state management) as well as persisting the data using `redux-persist`. The need for `redux-persist` is if we hard refresh a page without redux persist the data will be cleared off. So to handle it we are in need of redux-persist.

Now go to **index.tsx** and add the provider like below:

Now if you run the application you can see the output like this.

<iframe src="https://www.youtube.com/embed/qiXP9amLaQE?feature=oembed" width="700" height="393"></iframe>

Now we have created the Redux Form and validation. It’s time to add the actions to the form.

#### Creating form actions

Inside **redux** folder create a new folder named **actions** and then create another folder named **user.** Inside actions folder create a file named **index.ts.**

Inside **user,** folder create two files namely **add.ts** and **add.d.ts**

In **add.ts** file add the below code

In **add.d.ts** file add the types:

Now inside **redux** folder create another folder named **actionTypes** and then create a file named **userTypes.ts** and add the below code

export const ADD\_USER = 'ADD\_USER';

Now go to **reducers** folder which we have created earlier and create a new file named **user.ts** and add the below code:

Click save and go to **index.ts** inside **reducers** folder and import the `userReducer` like below:

Now go to pages -&gt; User -&gt; User.tsx and enable the dispatch calls and click save.

Now if you run the project, you could see the output like below:

<iframe src="https://www.youtube.com/embed/eBKzp3O9gOk" width="700" height="393"></iframe>

Congratulations you have created the redux wizard form using redux state management with typescript

In the next part, we will see how to write a test case using Jest for the redux form and redux actions.

### Git Link

[**nidhinkumar06/ReduxFormJest**  
\*This project was bootstrapped with Create React App. In the project directory, you can run: Runs the app in the…\*github.com](https://github.com/nidhinkumar06/ReduxFormJest.git)
