A Counter Application built with a custom hook and states implemented via useReducer.

Introduction

A counter application is a powerful productivity tool that helps us to count people, occurrences, instances, repetitions, etc.

In this article, we will discuss how to set up a custom counter hook with increment, decrement, reset, and setValue functions, as well as how to implement a combination of states with a useReducer that implements a counter with the same four features. We will also create a page for the custom hook, a page for the useReducer, a 404 page, and a page to test error boundary and good SEO.

Prerequisites

  • HTML

  • CSS

  • Basics for Javascript ES6

  • Basics of React.js library.

Steps in building the simple counter application

Before we proceed, I will be providing the file structure of the app we are going to build. This will help you to place files in the correct location. Please find the image below;

1. Install React

After the successful installation of Nodejs, install and set up a React app using the command below;

2. Setting up the custom counter hook

The next step is to create a custom hook called useCounter which contains the four basic functionalities: increment, decrement, reset, and setValue functions, and this was done by importing useState from react which enables us to get the previous count and current count once the button is clicked on. This hook will allow us to reuse these functions for manipulating the count in different components without having to rewrite the same code at different times.

The four major functions were then defined - increment, decrement, reset and setValue function(using the handleChange function) - see code below;

Now to set up the view, we need buttons that will show the 4 functionalities,

When pressing the increment button, function increment() will execute and the state count will increase by 1.

Similarly, when pressing the decrement button, function decrement() will execute and the state count will decrease by 1.

Also, when pressing the reset button, function reset() will execute and the state count will revert to the default value. The setValue function allows us to be able to input any value and so the count updates from the value filled in and this was done using the handleChange () function created to handle input change.

The react will re-render the view if a state or prop changes. So that the {count} inside the h3 tag will change according to the button clicks.

The localStorage function was updated to enable a state to hold the data we want to store, and then a useEffect hook was created which is used to pass the state as the second parameter. That way, whenever the state changes, the data in the localStorage is updated to the current value. This allows the data to persist even when the page is refreshed. The core functionality used to assist us in data storage was also handled in the useEffect() hook.

3. Implementing the useReducer

The useReducer hook was used to create a counter with the four basic functions that we implemented in our custom hook. This hook allows us to manage complex state logic and reduces the need for props drilling, making our code more organized and easier to understand.

The first step was to create a new file called countReducer.js, then the code below was added. This reducer manages the counter state and provides four actions for manipulating the count: INCREMENT, DECREMENT, RESET, and SET_VALUE.

The view was also set up the same way it was done in the custom hook, we created 4 buttons that shows the 4 functionalities in our UI. In this case, we used dispatch which allows us to send the type of action to the reducer function to perform its job, which, of course, is updating the state. The action to be executed is specified in our reducer function, which in turn, is passed to the useReducer. The reducer function will then return the updated state.

4. Creating the 404 page

It's important to have a 404 page in our application to handle cases when the user tries to access a non-existent page. To create a 404 page, you create an error 404 component that will render on routes that do not exist.

An error404.js file was created and the code below was added to create the 404 page which renders a message to the user.

The routing was done in the app.js file which renders the error 404 component for all the URLs not specified in routes.

5. Creating the Error Boundary page

An error boundary is a React component that catches JavaScript errors anywhere in its child component tree, logs those errors, and displays a fallback UI instead of the component tree that crashed.

The first step was to define a new class component called ErrorBoundary that extends React.Component, then 2 class methods were added called componentDidCatch and static getDerivedStateFromError. The componentDidCtach method takes two arguments: an error object and an error information object, while the static getDerivedStateFromError is used to handle fallback rendering.

To use the error boundary, you can wrap the component tree that you want to protect inside the 'ErrorBoundary' component in the index.js file;

To test the error boundary, a page was implemented, once the button increments up to 5 times, it throws an error. see code below;

6. Implementing a good SEO

Search Engine Optimization(SEO) refers to the process of making a website more visible on a search engine’s results page. The video below helped implement the SEO.

This site was deployed using Netlify.com following the steps below;

Conclusion

In conclusion, we have successfully set up a custom counter hook with increment, decrement, reset, and setValue functions, as well as implemented a combination of states with a useReducer that implements a counter with the same four features. We also created a page for the custom hook, a page for the useReducer, a 404 page, and a page to test error boundary and good SEO. These features allow us to easily manage and manipulate a counter state in our application.

Kindly find the link to view the project on the browser. Also, to view the files via GitHub, please click here.