React Counter – JavaScript Exercise #3

Overview

Create a simple React Counter component that displays a counter and two buttons to increment and decrement its value.

Requirements for React Counter

  • When the component first loads, the counter should start at 0.
  • Clicking the “+” button should increase the counter by 1.
  • Clicking the “-” button should decrease the counter by 1.
  • The counter value should never go below 0.
  • The component should update the counter value on the screen in real time as it changes.
  • The component should be implemented using functional components and React hooks.

Instructions

  1. Open up your preferred code editor and create a new file called “Counter.js”.
  2. Copy and paste the starter code provided above into the “Counter.js” file.
  3. Using the useState hook, initialize a state variable called “count” to 0.
  4. In the return statement of the component, update the h1 tag to display the current value of “count”.
  5. Create two new functions, “handleIncrement” and “handleDecrement”, that will be called when the “+” and “-” buttons are clicked respectively.
  6. In the “handleIncrement” function, update the “count” state by increasing it by 1.
  7. In the “handleDecrement” function, update the “count” state by decreasing it by 1 but making sure that the “count” value never goes below 0.
  8. Attach the “handleIncrement” function to the “+” button using the onClick attribute.
  9. Attach the “handleDecrement” function to the “-” button using the onClick attribute.
  10. Save the file and open up the “index.js” file.
  11. Import the “Counter” component and render it to the screen using ReactDOM.render.
  12. Open up your browser to view the running React application.
  13. Test your application by clicking the “+” and “-” buttons and verifying that the counter value updates correctly and does not go below 0.

Bonus Requirements

  • Add a new button that resets the counter back to 0 when clicked.
  • Add a new state variable called “disabled” that is initially set to false. When the counter value is 0, disable the “-” button so that it cannot be clicked. When the counter value is greater than 0, enable the “-” button.
  • Add some CSS styling to make the counter and buttons look more visually appealing.
  • Create a new component that renders multiple instances of the “Counter” component, each with its unique ID and title.
  • Add a feature that allows the user to increment and decrement the counter value by a specified amount.
  • Add a feature that saves the counter value to local storage, so that it persists even when the user closes and reopens the page.
  • Add a feature that displays a congratulatory message when the counter value reaches a certain milestone.
  • Add error handling to prevent the counter from exceeding set limits. Display an error message if the user tries to increment or decrement beyond the range.

Before you dive into the final output, I want to encourage you to take some time to work through the exercise yourself. I believe that active learning is the most effective way to learn and grow as a developer.

So, grab a pen and paper, fire up your code editor, and get ready to dive into the React Counter exercise. Once you have completed the exercise, feel free to return to this blog post to compare your solution to mine.

Output for the React Counter exercise

import React, { useState, useEffect } from 'react';
import './Counter.css';

function Counter(props) {
  // Initialize state variables
  const [count, setCount] = useState(0);
  const [disabled, setDisabled] = useState(false);

  // Define increment and decrement functions
  const handleIncrement = () => {
    setCount(count + props.step);
  };

  const handleDecrement = () => {
    if (count > 0) {
      setCount(count - props.step);
    }
  };

  const handleReset = () => {
    setCount(0);
  };

  // Disable "-" button if count is 0
  useEffect(() => {
    if (count === 0) {
      setDisabled(true);
    } else {
      setDisabled(false);
    }
  }, [count]);

  // Save count to local storage on update
  useEffect(() => {
    localStorage.setItem(props.id, count);
  }, [count]);

  // Load count from local storage on mount
  useEffect(() => {
    const savedCount = localStorage.getItem(props.id);
    if (savedCount) {
      setCount(Number(savedCount));
    }
  }, []);

  // Render component
  return (
    <div className="counter">
      <h2>{props.title}</h2>
      <div className="counter-buttons">
        <button onClick={handleDecrement} disabled={disabled}>-</button>
        <h3>{count}</h3>
        <button onClick={handleIncrement}>+</button>
      </div>
      <button className="reset-button" onClick={handleReset}>Reset</button>
    </div>
  );
}

export default Counter;
.counter {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  border: 2px solid #000;
  border-radius: 5px;
  margin-bottom: 1rem;
}

.counter h2 {
  margin-top: 0;
  margin-bottom: 1rem;
}

.counter-buttons {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1rem;
}

.counter-buttons button {
  font-size: 1.5rem;
  padding: 0.5rem 1rem;
  margin: 0 0.5rem;
  border-radius: 5px;
  background-color: #fff;
  color: #000;
  border: 2px solid #000;
  cursor: pointer;
}

.counter-buttons button:hover {
  background-color: #000;
  color: #fff;
}

.counter-buttons button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.counter h3 {
  margin: 0;
  font-size: 3rem;
}

.reset-button {
  font-size: 1.2rem;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  background-color: #000;
  color: #fff;
  border: none;
  cursor: pointer;
}

.reset-button:hover {
  background-color: #fff;
  color: #000;
}
  1. We import React, useState, and useEffect from the ‘react’ module, as well as a CSS file called ‘Counter.css’.
  2. We define a functional component called ‘Counter’ that takes in props for an ID, title, and step (the amount to increment or decrement the counter by).
  3. Inside the ‘Counter’ function, we initialize two state variables using the useState hook: ‘count’ is initially set to 0, and ‘disabled’ is initially set to false.
  4. We define three functions for handling the click events on the buttons: ‘handleIncrement’ adds the step value to the count, ‘handleDecrement’ subtracts the step value from the count but only if the count is greater than 0, and ‘handleReset’ sets the count back to 0.
  5. We use the useEffect hook to disable the “-” button if the count is 0, and enable it if the count is greater than 0. This effect runs whenever the count state variable changes.
  6. We use the useEffect hook to save the count to local storage whenever it changes. This effect runs whenever the count state variable changes.
  7. We use the useEffect hook to load the count from local storage when the component first mounts. This effect only runs once, when the component first mounts.
  8. Finally, we return some JSX that renders the counter, two buttons, and a reset button. We also pass in the ‘disabled’ variable as a prop to the “-” button, and we apply some CSS styles to make the component look nice.

Overall, this code provides a fully functional and interactive counter component that allows the user to increment and decrement the count by a specified step value, reset the count to 0, and save and load the count from local storage. The CSS styles provide a visually appealing design for the component.

Potential use cases for this counter component

  1. E-commerce website – The counter component helps to display the quantity of items in a customer’s shopping cart, allowing them to increase or decrease the quantity as needed.
  2. Fitness tracker app – The counter component helps to track the number of reps or sets completed during a workout, allowing the user to easily keep track of their progress.
  3. Time tracking app – The counter component helps to track the number of hours worked on a particular task or project, allowing the user to easily log their time and stay on top of deadlines.
  4. Recipe app – The counter component helps to adjust the serving size of a recipe, allowing the user to easily scale the ingredients up or down based on their needs.
  5. Gaming app – The counter component helps to keep track of points or scores during a game, allowing the user to easily update their score as they play.

These examples show how you can use the counter component in various applications. The flexibility and simplicity of the component make it a versatile tool for many different types of interfaces.

Thanks for taking this JavaScript exercise!

The React counter component we built in this exercise is a simple yet powerful tool. It can be used in many different contexts to enable user interaction and data tracking. Whether you’re building a simple web app, a complex e-commerce platform, or anything in between, this feature is valuable. The ability to increment and decrement values with a click of a button enhances user experience. It makes your application more engaging and interactive.

By following the steps outlined in this exercise, you should now have a good understanding of how to implement a basic counter component in React. With some additional styling and customization, you can easily adapt this component to fit your specific needs and design requirements.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top