Implementation of React Hooks, Context API and Reducer All-together

Yudhajit Adhikary
10 min readJul 21, 2019

--

In the past six months, you would have probably heard about React Context API and React Hooks. They are two kids in the react application and can make a huge impact on how we write React applications.

So, now let’s begin with the concepts.

Here, i have divided the article into different parts as follows:

1. What is Context API?

2. What is React Hooks?

3. What is Reducer?

4. System design

5. Implementation

i. What is Context API?

Context API gives us a clear and easy way to share states between different components without passing down the props all the time and React Hooks allows us to do a whole bunch of stuffs inside the functional components that we can normally do inside the class components. When we use these two concepts together, a magic happens that helps us in writing React code with shared data inside the application, similar to how Redux behaves without installing a third-party library.

A React Application consists of several components forming a Component tree and like before, when we used to share states within a component tree by passing it through all the components, the same thing can be done with props but sometimes that can become a little bit messy, by making our Component-tree and the application, as a whole bigger. So, we actually create a central repository to store data as state and then, share it between components without passing it down as props. So its going to clean the things up a little for us and its gonna make our work with the shared data much much easier. It sounds similar to Redux but its much simpler than Redux. So, Context API solves the problem of passing props everywhere even through components that doesn’t need the props where the components are actually acting as carrier components of props. So, Context API basically creates a place, where the shared states could be initially defined and setup and Context Provider allows every components inside the tree-system to use and share those states if needed.

ii. What is React Hooks?

React Hooks is a special function that allows us to do few things like using states or life-cycle methods etc. inside the functional components that we use inside the class components. We usually achieve this by using the following three functions,

UseState() -> to use state within the functional components.

UseEffect() -> to run the code, when a component renders or re-renders.

UseContext() -> allows us to use contexts in a functional component.

iii. What is Reducer?

If you are familiar with Redux, then you must have heard about Reducer. Reducer takes two parameters, which are action and state. It actually acts as a manipulator that manipulates the state whenever an action is dispatched, depending on which type of action is being dispatched such as storing a data by adding the input fields value to state on clicking the Submit button.

The main work-flow of Reducer is as follows:

Whenever an action occurs, it dispatches the action type and a payload, which contains the essential data needed by the Reducer to manipulate the state .

Now, I believe, you would have got a basic idea of Context API, React Hooks and Reducer . So, to increase your hold on these concepts, we are gonna create a simple Book List application, where all the three concepts will be applied. Before diving into the implementation directly, first, I would like to explain the whole application-flow that we are going to develop.

Here, the application that we are gonna develop is a book-List application in which you can list out all the books you want to read and when you finish reading a book, you can remove that book from the book-list.

So, when we type npx create-react-app <project name> in our visual studio code terminal, we get the react boilerplate by default and if we carefully see the folder structure that we would get inside the project folder, we will get to see the App.js consisting of all the components that are being rendered in the boilerplate and the index.html file that uses App.js as the root of the react component tree.

Now, we have to transfer several states between the components to make the application work properly. So, here the Context API and Hooks come into picture as all the components which we are gonna use to build the application will be our functional components. As we have already seen earlier that the Context API will be the central repository where all the states will get stored. But to make those states accessible for all the components in the application, we will wrap the whole application, i.e. App.js(root) with a Context Provider .

As discussed earlier, our components inside this application will be functional components, so, React Hooks allows us to use those states inside functional components with the help of several functions like UseState(), UseEffect() and UseContext(). Now, we discussed everything except the Reducer’s role in the application. So, the reducer is actually the manipulator of the state which manipulates the states whenever an action is dispatched according to the action type; we will discuss about it later during implementation of the application.

As of now, we have discussed the workflow of the application. Now the final thing is the design of the application. As our application is a simple single-page application having four components; Navbar, BookDetails, BookList and NewBookForm, Navbar will contain a welcome message and the number of books present in our BookList. BookDetails contains the list of Books and each Book will have a Book Name and Author Name and finally, the NewBookForm is the form that will be used to add books in the book-list and if we click on a book inside the booklist, it will be removed from the booklist.

Now let’s see the folder structure of our application:

As you can see our components folder inside src is having four JavaScript files which represents four components as Navbar.js, BookList.js, BookDetails.js and NewBook.js. Contexts Folder consists of BookContext.js, which is a central store house of all the states. Reducer Folder consists of BookReducer.js that manipulates the state whenever an action is dispatched by components according to the action type.

So, let’s start building the application with App.js(Root component)

Here, App.js imports four components from components folder and BookContextProvider from BookContext.js, which acts as the Context Provider of the application. But we have not created the Components and the ContextAPI till now.

So, let’s create the ContextAPI first.

So, here BookContext.js is acting as a Context API :

const BookContext = createContext();

createContext() creates the Context API which will store the states and BookContextProvider is a variable having two states, Books, an array of objects which consists of the book details and Dispatch, a function which dispatches an action type and payload. We will import BookContext inside components, so that the components can access the states.

We will discuss about action dispatch later which demonstrates how the action dispatches within a couple of minutes and lastly the BookContext.Provider which is the wrapper that brings all the states in its value tag by wrapping all the children into App.js to make the states(Books and Dispatch) available for all the components to access. Now, there are many stuffs in this code which you may not understand right now and those things will be clear to you at the end of this discussion.

So, now let’s start creating our first component, Navbar.js

So, In Navbar.js, to use the context inside functional components we have used UseContext(). Now we have done a little bit of Destructuring to fetch the books state from the BookContext and used the {Books.Length} to get the number of books inside the Book-List.

Now, our next Component is NewBookForm.js

So, In NewBookForm.js, to use the context inside functional components we have used UseContext() and done a little bit of Destructuring and fetched the dispatch method from the BookContext. We have also used UseState() to use state inside functional components.

Hence, the two states are title and author,

Const [title, setTitle] =useState (‘ ’);

Const [author, setAuthor] =useState (‘ ’);

So, title and author are the states that we are using inside functional components, and setTitle( ) and setAuthor( ) are the functions to set the values of the state. The initial values of both the states are ‘ ’.

The Above expressions are the syntaxes of declaring a state using UseState() inside functional Components. There are text fields named Book Name and Book Author, on changing which we are setting the values of the states by calling the setTitle() and setAuthor() functions.

And dispatching an object having action.type:ADD-BOOK and a payload (book) having the two input value Book name and Book Author ,means the component is indicating the context Api to add the book and send the details of the book to ContextApi in the form of payload. Now we will see how the data is received and manipulated by the ContextApi, So when the component dispatch the action ,ContextApi receive the dispatched method and use Reducer to manipulate the data.If you revisit the BookContext.js file you will see that the BookContext is functional file and to use reducer inside it, we use another hooks function called useReducer ().

The following is the useReducer() function syntax:

Const [book, dispatch] = useReducer (bookReducer, [], () => {

//callback function after completing the manipulation of state

})

Here first parameter is the name of the reducer to be used, second parameter is the initial value of the state to be manipulated, and third is the callback function that is to be performed after the completion of manipulation.

Now, let’s see the BookDetails.js and BookList.js

In BookList we are de-structuring books states from BookContext and map through it and sending it as props with an unique id to BookDetails.

In BookDetails we are de-structuring dispatch method from BookContext and when the BookDetails components is clicked the dispatch function dispatches the action.type and send the Book id as payload to the Reducer so that the Context Provider can understand which Book is to be removed.

But we have not created the Reducer files till now, let’s create the Reducer file now

The Reducer takes two parameters one is state and another is action, and the reducer use to manipulate the state according to the action. type it is receiving, For example, if action.type=’ADD-BOOK’ then the reducer is updating the data by […state,{title:action.book.title},{author:action.book.author}] and it is return to Context Provider .And when it is done the callback function of Context Api is performed.

Before Discussing about callback function I want to go through the concept of Local Storage. If we type localStorage in the console we will get the name of the localStorage Instances .To create localStorage object we have to type localStorage.setItem(‘variable name’,value).means if we write Local.setItem(‘book’,InnerEngineering) it will create a local instance of name book having value InnerEngineering. JSON.stringify() method converts JavaScript object into strings. As when sending data to web server the data has to be a string. To get the value of local instance we type localItem.getItem(‘name’).While receiving data from a web server ,the data is always string .So JSON.parse() converts data into Json format. And Last thing is useEffect() which is a react hooks function which executes whenever a component render , re-render or state value changes. The syntax of useEffect() is as follows:

useEffect (()=>{

//function is to be execute, [ on change of which state the useEffect function should execute]

})

So, in Reducer File, useEffect( ) is called on every change in book’s state and local Instance named book is created. This local Instance is then stringified to send it to web server after that by the callback function the received book local instance is convert into object and send to Context Provider, Thus Context Provider will have the updated value of the state. And the components inside component tree can access the data and reflect the changes in the front end. So Hurry, our Book List Application is now ready .I have not uploaded the Scss part of the code Because I want to keep the whole attention to the conceptual part of the application.

So, i hope my blog is gonna be really helpful to you,You can find the whole code in my GitHub repo

CODE:

If you are a beginner who is passionate about React Redux , ContextAPI and React Hooks. I will always be encouraging you people to play and try new things around these concepts.

Happy Coding…:)

--

--

Yudhajit Adhikary
Yudhajit Adhikary

Written by Yudhajit Adhikary

Web developer by profession,Photographer,Blog Writer,Singer,Pianist,Seeker of Solution

Responses (5)