How I Built A Custom Counter Project Using React.

Tos
5 min readJan 9, 2023

Welcome to my first post on medium as a Front End Developer as I close the chapter to the journey of becoming a data scientist.

Your work is going to fill a large part of your life, and the only way to be truly satiated is to do what you believe is great work .And the only way to do great work is to love what you do. — Steve Jobs

The above quote answers one question I’m constantly asked regarding why I changed my track. I realized it wasn’t what I wanted after I completed a mentorship program with SheCodeAfrica.

For someone who makes progress when there is structure and a form of accountability, I enrolled with a tech school called Alt School. This decision played a significant part in my growth and provided me with a road map for this new learning track. Fast-forward to 7 months, and I am here writing an article on how I achieved building a custom counter using a React framework.

React

React is a free and open-source front-end Javascript library developed by Facebook. It’s used for building interactive user interfaces and web applications quickly and efficiently with significantly less code. ReactJS’s primary goal is to create User Interfaces. It uses virtual DOM, a copy of the actual DOM (JavaScript object).

Applications in react are developed by creating reusable components, which are at first single pieces of a final interface and, when finally assembled, form the complete application user interface.

BASIC TERMS USED IN REACT

  1. Component: It is a building block of react applications. It contains reusable code. It comes in two types Class and Function components.
  2. State: It is a built-in React object where you store data or information, or property values belonging to the components.
  3. Functional Components: It is a simple javascript function that accepts props as an argument and returns a react element.
  4. Class Components: It requires you to extend from react a component and create a render function that returns a react element.
  5. Props: It’s used to pass data from parent to child components. It is an integral part of React.
  6. Hooks: These are built-in functions in React that allow you to manage state and other features in react. Their name starts from use. They help to write concise and clear code. Examples of hooks used in this project are useState, useReducer, etc.

A Practical Approach to Building a Custom Counter Project

Step One: Run a create-react-app in a terminal of your choice.

The create-react-app is a node package command-line tool that generates a file system with several files and folders, as seen below in the node package.

The npm start is a command line that activates the development server that opens a new tab in your browser.

image of the command lines to be in the terminal
An image with a dark background containing folders and packages of react.js
image of the node package

Step Two: Setting up a useState hook component.v

After running these command lines and successfully installing the node modules, we can create a Custom Counter Project by opening the src/App.js file to delete the default code present and create folders and files containing new components to build the counter application.

import { useState } from "react";

function useCounterHook(initialCount = 0) {
const [count, setCount] = useState(initialCount);
const handleIncrement = () => {
setCount((prevValue) => prevValue + 1);
};
const handleDecrement = () => {
setCount((prevValue) => prevValue - 1);
};
const handleReset = () => {
setCount(initialCount);
};
const setValue = (parameter) => {
setCount(parameter);
};
return [count, handleIncrement, handleDecrement, handleReset, setValue];
}
export default useCounterHook;

The first line of code above imports the useState hook from the react module to create the count state and initialize it to 0. The setCount changes the value of the count.

Step Three: Implement the useState hook in a Counter component.

The state, useState above, was implemented in this counter, named CounterOne. In addition, buttons were added to enable the functionality of the counter, and when you click these buttons, the handleIncrement, handleDecrement, handleReset, etc., will run.

Image of the useState hook implemented in counter one

Step Four: Set up another counter component to implement a useReducer state.

The useReducer hook stores and updates states similar to the useState hook. It accepts a reducer as its first parameter and the initial state as the second parameter.

function useCounterReducer(initialState, action) {
switch (action.type) {
case "handleIncrement":
return { ...initialState, count: initialState.count + 1 };
case "handleReset":
return { ...initialState, count: (initialState.count = 0) };
case "handleDecrement":
return { ...initialState, count: initialState.count - 1 };
case "setValue":
return { ...initialState, count: Number(action.payload.newCount) };
default:
return initialState;
}
}
export default useCounterReducer

Here, we import useReducer instead of useState hook. Also, in this component, we use dispatch instead of setCount.

Image of the useReducer hook implemented in counter Two

import React, { useReducer, useRef } from "react";
import { Helmet } from "react-helmet";
import useCounterReducer from "../Pages/UseCounterReducer";
import ErrorBoundary from "../Pages/ErrorBoundary";

const initialState = { count: 0, setCount: 0 };

function CounterTwo() {
const [count, dispatch] = useReducer(useCounterReducer, initialState);
const inputRef = useRef();

function setTheCount(ref) {
console.log(ref);
dispatch({
type: "setValue",
payload: { newCount: ref.current.value },
});
ref.currentValue = "";
}

return (
<>
<ErrorBoundary>
<main className="card-main">
<Helmet>
<title>Counter App One Home Page</title>
<meta
name="description"
content="A counter app with an implementation of increase, decrease, reset and set value using a hook called useReducer"
/>
</Helmet>
<div className="card-center">
<div className="card-body">
<div className="card-action">
<div className="card-btn"></div>
<div>Count = {count.count}</div>
<button
className="increment-btn"
onClick={() => dispatch({ type: "handleIncrement" })}>
Increment
</button>
<button
className="decrement-btn"
onClick={() => dispatch({ type: "handleDecrement" })}>
Decrement
</button>
<button
className="reset-btn"
onClick={() => dispatch({ type: "handleReset" })}>
RESET
</button>

<div>
<input
className="input-value"
placeholder={"Number"}
type={"number"}
ref={inputRef}
/>
<button
className="set-value"
onClick={(e) => {
setTheCount(inputRef);
}}>
Set
</button>
</div>
</div>
</div>
</div>
</main>
</ErrorBoundary>
</>
);
}

export default CounterTwo;

Note: for every component created, it’s essential to import simultaneously into the App.js after exporting each component.

This is the final code look of the App.js file:

 import React, { Component } from "react";
import { Route, Routes } from "react-router-dom";
import CounterOne from "./Component/CounterOne";
import ErrorBoundary from "./Pages/ErrorBoundary";
import ErrorPage from "./Pages/404Page";
import "./App.css";
import CounterTwo from "./Component/CounterTwo";
import Navbar from "./Component/Navbar";
import BuggyCounter from "./Component/BuggyCounter";
// import { useState } from "react";

class App extends Component {
render() {
return (
<>
<Navbar />
{/* wrapping child component with */}
<ErrorBoundary>
<Routes>
<Route path="/" element={<CounterTwo />} />
<Route path="/custom-hook" element={<CounterOne />} />
<Route path="/error-occurred" element={<BuggyCounter />} />
<Route path="/page-not-found" element={<ErrorPage />} />
</Routes>
</ErrorBoundary>
</>
);
}
}
export default App;

If you read to this point, thank you. The code used in this project can be found in this github repository and a link to check out the functionality in real time.

--

--