How to create React Context using useReducer and useContext hook with TypeScript

In this tutorial, I am going to share state across multiple components using React Context. React Context is an interface for sharing information with other components without explicitly passing the data as a props. React Context API allows a central store where all the data lives (like Redux). The store can be used for any Components directly. 

When shall I use Context?

The main idea of using Context is to allow components to use global data and only re-render when the data changed. Context also solves the props drilling problem, when an application needs to pass props from parent to children. 

 


What I want to achieve ...

Create a simple user list (Add / Delete operation) application by leveraging React Context using useReducer & useContext hooks. 

* React Application creation with TypeScript

* Add bootstrap and SCSS for Styling

* Create Simple Route & user Form Creation

* Context Initialization & Reducer creation with Add & Delete functionality

* Use Context data using Consumer & useContext hook

* Demo & Source Code

context-react-typescript-hook

 

 

Let's start the journey...

React Application creation with TypeScript

Create yours react typescript project with SCSS support.

npx create-react-app redux-demo-app --template typescript

npm install --save react-router-dom @types/react-router-dom @types/react

 

Once installation is completed, execute the "npm run start" command from your terminal in order to lunch the newly created application.


Add bootstrap and SCSS for Styling

Now Adding Bootstrap and SCSS

npm install --save bootstrap react-bootstrap 

npm install --save node-sass

 

Create style.scss file and import bootstrap library reference.

@import "~bootstrap/scss/bootstrap";

Refresh the application, and bootstrap with SCSS support has been added to your application.


Create Simple Route & user Form Creation

Now in this application, I am going to have only two routes Dashboard & User. 

context-react-typescript-route

​​​​I have created a Header.tsx & Header.module.scss file and add the router information there as like below -

Create User Form

I have created a simple user form to take user input. It has a dropdown, a text field and a save button. 

context-react-typescript-form

UserForm.tsx file - 

Dropdown.tsx file

 


Context Initialization & Reducer creation with Add & Delete functionality

In this step, I am going to create a custom UserContext, UserReducer & a User model. 

UserContext.ts

import { createContext } from 'react';

import { UserData } from './UserData';

 

export interface IContextProvider {

userList: UserData[];

setUserList: (arg: UserData) => void

}

 

const UserContext = createContext<IContextProvider>({} as IContextProvider);

export default UserContext;

 

UserReducer.ts

import { UserData } from "./UserData";

 

export const UserReducer = (state: any, item: UserData) => {

switch (item.actionType) {

 

case "ADD":

return [...state, item];

 

case "DELETE":

return [

...state.filter((user: any) => user.id !== item.id)

]

 

case "UPDATE":

break;

 

default:

return state;

}

}

 

UserData.ts

export interface UserData {

id: number;

role: string;

name: string;

 

actionType?: string;

}

 

Now Context creation is done, now I need to add it to React ecosystem, so that context store data can be available across components. So to do that, we need to use a component called a Provider. The Provider is a component that sets the data and then wraps some child components. Any wrapped child components will have access to data from the Provider with the useContext Hook.

 


Use Context data using Consumer & useContext hook

Now, we can add and delete user data into context using useContext hook. Whenever we are calling setUserList() method, it called the reducer method with mentioned action type. Based on action type we are modifying the state object and return it to the Component. 

// get context

const { userList, setUserList } = useContext(UserContext);

 

// Add user data into UserContext

const formSubmit = (user: UserData) => {

user.actionType = "ADD";

setUserList(user);

}

 

// Delete user data into UserContext

const deleteUser = (user: UserData) => {

user.actionType = "DELETE";

setUserList(user);

}

 

Have a look at the complete code in Dashboard Component. 

There is two way we can read context data. 

  • Using Consumer - it can be added as a component wrapped with child component and using context we can read data from Context store. 

Example - 

  • Using useContext hook - it can be used in functional component and get the object from Context store. 

Example - 

 


Demo time - 

Happy Coding!