Skip to Content
Lab 1

React Counter with useEffect

Scenario

You have been tasked to build an advanced counter application. This project will challenge you to go beyond simple state updates by requiring you to manage multiple state dependencies, implement side effects using the useEffect hook (including proper cleanup), and handle more complex state update logic. The goal is to solidify your understanding of useState and useEffect in a practical context, focusing on how they work together to create interactive and responsive components.


Learning Objectives

Upon successful completion of this lab, you will be able to:

  • Implement and manage multiple pieces of state within a single component using useState.
  • Utilize the useEffect hook to perform side effects in response to state changes.
  • Implement proper cleanup functions within useEffect to prevent memory leaks or unexpected behavior.
  • Write state update logic that correctly handles dependencies and previous state.
  • Apply your knowledge to build a feature-rich counter with history tracking, auto-save, keyboard interactions, and a reset mechanism.

Project Requirements

Build a React application that features an advanced counter. The specific features are outlined below.

Core Counter Functionality

  1. Display Current Count: Show the current count, initialized to 0.
  2. Increment Button: A button to increase the count by 1.
  3. Decrement Button: A button to decrease the count by 1.

Advanced Features

  1. History Tracking:

    • Keep a history of all count values. Every time the count changes, add the new count to an array of previous counts.
    • Display this history list to the user (e.g., “Previous counts: 0, 1, 2, 1, 2, 3”).
  2. Auto-Save Functionality:

    • Use useEffect to save the current count to local storage whenever it changes.
    • Ensure you handle potential race conditions or cleanup if the count changes again before the “save” completes. (Hint: cleanup function in useEffect).
  3. Keyboard Event Listeners:

    • Allow the user to increment the count by pressing the “ArrowUp” key.
    • Allow the user to decrement the count by pressing the “ArrowDown” key.
    • Use useEffect to add and remove these event listeners to the document.
    • Ensure event listeners are cleaned up when the component unmounts or is no longer active.
  4. Reset Mechanism:

    • Implement a button to reset the count back to 0.
    • This reset should also clear the tracked history of counts.
  5. Step Input:

    • Add an input field where the user can define a custom “step” value.
    • The increment and decrement buttons should then use this step value instead of 1.
    • Consider how changes to the step value affect the counter and its history.

Implementation Guidelines

  • Create a new React component for your counter (e.g., AdvancedCounter.tsx).
  • Use useState to manage the current count, history array, and any other necessary local state.
  • Use useEffect for side effects like auto-saving and adding/removing keyboard event listeners.
  • Pay close attention to the dependency arrays in your useEffect hooks to control when they re-run.
  • Ensure all useEffect hooks that set up subscriptions or event listeners have proper cleanup functions.

Example Solution

Counter

Current Count: 0
Changes saved.

Count History:

No history yet.

Use ArrowUp to increment and ArrowDown to decrement.

Submission

Submit your project on Canvas via a GitHub link that includes all necessary files.


Grading Rubric

This lab is graded on a Complete / Incomplete basis. To achieve a “Complete” status, your submission must:

  • Successfully implement all Core Counter Functionality.
  • Successfully implement at least 3 out of the 4 Advanced Features (History Tracking, Auto-Save, Keyboard Listeners, Reset Mechanism).
  • Demonstrate correct usage of useState for state management.
  • Demonstrate correct usage of useEffect for side effects, including appropriate dependency arrays.
  • Implement proper cleanup for any effects that require it (e.g., event listeners, timers from auto-save simulation).
  • The application should run without console errors (related to React, not build environment warnings).
Note

Focus on understanding and correctly applying useState and useEffect. The visual presentation of the counter is secondary to its functional correctness and the proper use of React Hooks.

💡
Tip

Break down each feature into smaller pieces. Test each piece as you go. Use console.log statements liberally during development to understand state changes and effect executions.