DEV Community

Cover image for How to create a Counter Application using custom hooks and useReducer in React with good SEO, Error Boundary and 404 page
B U C H M A NšŸ’»
B U C H M A NšŸ’»

Posted on • Edited on

How to create a Counter Application using custom hooks and useReducer in React with good SEO, Error Boundary and 404 page

Building your own Hooks lets you extract component logic into reusable functions.

Hooks are a new addition in React 16.8. They let you use state and other React features in functional components. Examples are:

  • useState
  • useEffect
  • useContext
  • useReducer
  • useMemo etc

In this article, Iā€™ll walk you through the steps in building a Counter application in React using custom hooks and useReducer. Weā€™ll be implementing React-router for the navigation, Error Boundary, 404 page and SEO in React.

Prerequisites

Before we begin this tutorial, youā€™ll need the following

  • Web browser
  • Nodejs installed for the ā€˜npmā€™ command tool
  • DevTools
  • Reactjs installed
  • React Router installed
  • Error Boundary installed

Web Browser

A web browser, or simply 'browser,' is an application used to access and view websites. Common web browsers include Microsoft Edge, Internet Explorer, Google Chrome, Mozilla Firefox, and Apple Safari.

Nodejs

Node.jsĀ® is an open-source, cross-platform JavaScript runtime environment.

It is used for server-side programming, and primarily deployed for non-blocking, event-driven servers, such as traditional web sites and back-end API services, but was originally designed with real-time, push-based architectures in mind.

Node. js is not a programming language. Rather, it's a runtime environment that's used to run JavaScript outside the browser.

DevTools

Developer tools (or "development tools" or short "DevTools") are programs that allow a developer to create, test and debug software. Current browsers provide integrated developer tools, which allow to inspect a website.

Reactjs

A JavaScript library for building user interfaces.

React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.

If youā€™re learning React, we recommend Create React App. It is the most popular way to try out React and build a new single-page, client-side application. Itā€™s made for React but isnā€™t opinionated about routing or data fetching.

First, install Node.js. Then open your terminal and run this line to create a project:


npx create-react-app my-app

Enter fullscreen mode Exit fullscreen mode

Now you can run your app with:


cd my-app
npm start

Enter fullscreen mode Exit fullscreen mode

React Router

React Router is a standard library system built on top of the React and used to create routing in the React application using React Router Package. It provides the synchronous URL on the browser with data that will be displayed on the web page.

To install using npm:


npm i react-router-dom

Enter fullscreen mode Exit fullscreen mode

Error Boundary

A JavaScript error in a part of the UI shouldnā€™t break the whole app. To solve this problem for React users, React 16 introduces a new concept of an ā€œerror boundaryā€.
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies:


npm install --save react-error-boundary

Enter fullscreen mode Exit fullscreen mode

The simplest way to use is to wrap it around any component that may throw an error. This will handle errors thrown by that component and its descendants too.


import {ErrorBoundary} from 'react-error-boundary'

function ErrorFallback({error, resetErrorBoundary}) {
  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  )
}

const ui = (
  <ErrorBoundary
    FallbackComponent={ErrorFallback}
    onReset={() => {
      // reset the state of your app so the error doesn't happen again
    }}
  >
    <ComponentThatMayError />
  </ErrorBoundary>
)

Enter fullscreen mode Exit fullscreen mode

Implementing a Counter Application with Custom Hook

React comes with several built-in Hooks like useState, useContext, and useEffect. Sometimes, youā€™ll wish that there was a Hook for some more specific purpose: for example, to fetch data, to keep track of whether the user is online, or to connect to a chat room. You might not find these Hooks in React, but you can create your own Hooks for your applicationā€™s needs. In this context, weā€™ll be creating our custom hook used in a Counter Application, implementing the following functions:

  • Increment
  • Decrement
  • Reset
  • setValue

Weā€™ll create a folder named useCounter. Then implement the following functions manually (Increment, Decrement, Reset and setValue)


import { useState } from 'react'

import { useErrorHandler } from "react-error-boundary";

const MAX_COUNT_ALLOWED = 10;

function useCounter(initialCount = 0, count) {
  const [value, setValue] = useState(initialCount);
  const handleError = useErrorHandler()

  const increment = () => {
    try {
      if (value === MAX_COUNT_ALLOWED) {
        throw new Error("Count limit exceeded");
      } else {
        setValue(prevCount => prevCount + count);
      }
    } catch (error) {
      handleError(error)
    }
  };

  const decrement = () => {
    setValue(prevCount => prevCount - count);
  };

  const reset = () => {
    setValue(0);
  };

  return [value, increment, decrement, reset]
}

export default useCounter


Enter fullscreen mode Exit fullscreen mode

First, we import the useState component from React, then we create a functional component that takes in an initial value and returns a set of values.

We then created a count state inside the function which would be the value of the counter.

We further created the increment, decrement and reset functions inside the useCounter function. These will add functionality to the Counter application (increase and decrease of values)

Now that weā€™ve created our custom hook, we should apply it to our application.

Weā€™ll create a component called CustomCounter.js, import useCounter from the hooks folder we created, and apply the functionalities appropriately.


import React from "react";
import useCounter from "../hooks/useCounter";
import { Helmet } from "react-helmet-async";

export const CustomCounter = () => {
  const [value, increment, decrement, reset] = useCounter(0, 1);
  return (
    <div>
      <Helmet>
        <title>Custom Counter Page</title>
        <meta name="description" content="Counter Application using a Custom hook" />
        <link rel="canonical" href="custom-counter" />
      </Helmet>
      <div className="value">{value}</div>
      <div className="max_text">Maximum of 10 counts</div>
      <button onClick={increment} className='increment'>Increment</button>
      <button onClick={decrement} className='decrement'>Decrement</button>
      <button onClick={reset} className='reset'>Reset</button>
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

Top comments (0)