Implementing Counter App With useReducer: A Retrospective Technical Review

Implementing Counter App With useReducer: A Retrospective Technical Review

ยท

5 min read

React.js is a popular JavaScript library for building user interfaces, and it has become a go-to choice for many developers building modern web applications. In this article, we will take a retrospective look at the process of implementing a simple counter app using React.js. We'll cover the basics of setting up a React.js project, implementing features like state and hooks, and deploying the app to the web.

Requirements for Implementing a Counter App in React.js

  • Node.js installed

  • Code editor - I prefer Visual Studio Code

  • React

  • Netlify account

Step 1: Setting Up a React.js Project

The first step in implementing our counter app is setting up a new React.js project. There are a few different ways to do this, but the easiest is probably using the create-react-app tool. This tool sets up a new project with all the necessary dependencies and configuration files, making it easy to get started building your app right away.

To install create-react-app, open up a terminal and run the following command:

npm install -g create-react-app

Next, create a new project by running the following command:

create-react-app counter-app

This will create a new folder called "counter-app" with all the necessary files for a new React.js project.

Step 2: Building the Counter App with useReducer

With our project set up, we can start building out the functionality of our counter app. In React.js, components are the building blocks of an app, and they are responsible for rendering UI and managing the state.

The useReducer hook is a powerful way to manage state in React. It allows us to define a reducer function that handles the state updates in response to actions. In our counter app, the count is stored in state, and we can update it by dispatching actions that are handled by the reducer function.

To build the counter app, we started by creating the reducer function and the initial state. The reducer function takes in the current state and an action, and it returns a new state based on the action. In our case, we had three actions: "INCREASE", "DECREASE" and "RESET".

Next, we used the useReducer hook to get the current state and the dispatch function. We passed the reducer function and the initial state to the useReducer hook, and it returned the current state and the dispatch function.

  • Create a new file called "useCounter.jsx" in the "src" folder of our project. Then, we'll add the following code:
import { useReducer } from "react";

const useCounter = () => {
  const ACTIONS = {
    INCREASE: "increase",
    DECREASE: "decrease",
    RESET: "reset",
    SET_VALUE : "setValue"
  };
  function setValue(value, count) {
    let num = Number(value)
    if(String(num) === "NaN" || value === "") {
        return count;
    }
    return num;
  }
  function reducer(count, action) {
    switch (action.type) {
      case ACTIONS.SET_VALUE:
        return setValue(action.payload, count);
      case ACTIONS.INCREASE:
        return ++count;
      case ACTIONS.DECREASE:
        return --count;
      case ACTIONS.RESET:
        return 0;
      default:
        return count;
    }
  }
  const [count, dispatch] = useReducer(reducer, 0);

  return { count, dispatch, ACTIONS };
};
export default useCounter;
  • Finally, we used the dispatch function to update the state when the user clicks the increment, decrement or reset buttons. We passed the appropriate action to the dispatch function, and the reducer function was called to update the state.

    Create a new file called "Counter.jsx" in the "src" folder of our project. Then, we'll add the following code:

import React from "react";
import useCounter from "./Components/useCounter";
import "./Styles/Counter.css";

export default function Counter() {
  const { count, dispatch, ACTIONS } = useCounter();
  return (
    <div>
      <h1 className="counter"> Counter</h1>
      <div className="counter-container">
        <input
        style={{borderRadius: "5px"}}
          type="text"
          placeholder="Type in a count value..."
          onChange={(e) =>
            dispatch({ type: ACTIONS.SET_VALUE, payload: e.target.value })
          }
        />
        <h2>Count : <span   style={{
          color: count > 0 ? 'green' : 'red',
          // color: count > 0 ? 'white' : 'powderblue',
        }} >{count}
          </span> </h2>
        <div>
        <button
            className="dlt-btn"
            onClick={() => {
              dispatch({ type: ACTIONS.DECREASE });
            }}
          >
            Decrement
          </button>
          <button
            className="add-btn"
            onClick={() => {
              dispatch({ type: ACTIONS.INCREASE });
            }}
          >
            Increment
          </button>

        </div>

        <button
          onClick={() => {
            dispatch({ type: ACTIONS.RESET });
          }}
          className="rst-btn"
        >
          Reset
        </button>
      </div>
    </div>
  );
}

Step3: Custom Styling

Once we had the core functionality in place, we moved on to styling the app. We used CSS to give the app a unique look and feel, and we were able to customize the appearance to our liking. The appropriate CSS class and import have been done in the code above.

.counter{
    text-align: center;
    font-size: 3rem;
    font-weight: 900;
}

.counter-container {
    height: 50vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin: 20px 0;
}
.add-btn{
    background-color: #6568f4;
    color: #fff;
    padding: 2px;
}
.add-btn:hover{
    background-color: #fff;
    color: #6568f4;
    border: 1px solid #6568f4;

}
.dlt-btn{
    background-color: red;
    color: #fff;
    padding: 2px;
}
.dlt-btn:hover{
    background-color: white;
    color: red;
    border: 1px solid red;

}
.rst-btn{

    padding: 1rem 3rem;

    background-color: #282c34;
    color: #fff;
}

.rst-btn:hover{

    border: 1px solid black;
    background-color: #fff;
    color: black;
}
.counter-container h2 {
    font-size: 2.5rem;
    margin: 20px 0;
}

.counter-container input {
    padding: .5rem;
}

.counter-container button {
    margin: 20px;
    padding: 1rem;
    font-size: 1rem;
    font-weight: bold;
    border-radius: 5px;
}

Step 4: Deploying the App to Netlify

After completing the app, we wanted to make it available to users on the web. To do this, we deployed the app to Netlify. Netlify is a popular platform for hosting static sites and single-page applications, and it offers several features that make it easy to deploy and manage web projects.

We used the Netlify CLI to deploy the app, and the process was straightforward. The app was live on the web in just a few minutes, and we were able to share the URL with users to try out the app.

Conclusion

In conclusion, building a counter app with React.js was a great learning experience. While there were certainly some challenges along the way, we were able to overcome them and create a functional and visually appealing app.

View the full Github Code Here

Visit the deployed site Here

Below is what the counter app looks like ๐Ÿ˜Š

Congratulations ๐ŸŽ‰, We have successfully Deployed Our React Counter Application. Happy Coding ๐Ÿ˜Š

ย