Counter Component

beginner
15 min

Explorer

2
āš›ļø
Counter.jsx
šŸŽØ
Counter.css

Click files to view code →

React Counter Component Tutorial

1. What is the Question and What to Achieve Here

Build an interactive counter component that allows users to increment, decrement, and reset a numerical value. This component should display the current count and provide three buttons for user interaction.

[!TIP] Goal

  • Display a numerical counter value
  • Increment the counter by 1
  • Decrement the counter by 1
  • Reset the counter to 0 (or initial value)
  • Update the UI reactively when the counter changes

2. How to Solve

Use React's

text
useState
hook to manage the counter value as component state. When buttons are clicked, update the state which will trigger a re-render and display the new value.

3. What Are the Things That Need to Be Gathered

[!IMPORTANT] Requirements

  • React library (with hooks support)
  • Basic understanding of:
    • Component structure
    • Event handlers
    • State management with
      text
      useState
    • Click events

No external dependencies needed - this can be built with vanilla React.

4. Key Topics to Consider and Plan of Action

Key Topics:

  • State Management: Using
    text
    useState
    to track the counter value
  • Event Handling: Attaching onClick handlers to buttons
  • Immutability: Updating state properly (not mutating directly)
  • Component Re-rendering: Understanding when React re-renders

Plan of Action:

  1. Create a functional component called
    text
    Counter
  2. Initialize state with
    text
    useState(0)
  3. Create three handler functions:
    text
    increment
    ,
    text
    decrement
    ,
    text
    reset
  4. Render the UI with count display and three buttons
  5. Connect handlers to buttons via onClick props
  6. (Optional) Add styling for better UX

5. Code the Question

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

function Counter() {
  // Initialize state with default value of 0
  const [count, setCount] = useState(0);

  // Handler functions
  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

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

  return (
    <div className="counter-container">
      <h2>Counter Component</h2>
      
      <div className="counter-display">
        <h1>{count}</h1>
      </div>

      <div className="counter-buttons">
        <button onClick={decrement} className="btn btn-decrement">
          - Decrement
        </button>
        
        <button onClick={reset} className="btn btn-reset">
          Reset
        </button>
        
        <button onClick={increment} className="btn btn-increment">
          + Increment
        </button>
      </div>
    </div>
  );
}

export default Counter;

CSS Styling (Counter.css):

cssShowing 50 of 60 lines
.counter-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2rem;
  font-family: Arial, sans-serif;
}

.counter-display {
  margin: 2rem 0;
  padding: 2rem;
  background-color: #f0f0f0;
  border-radius: 10px;
  min-width: 200px;
  text-align: center;
}

.counter-display h1 {
  margin: 0;
  font-size: 4rem;
  color: #333;
}

.counter-buttons {
  display: flex;
  gap: 1rem;
}

.btn {
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: transform 0.1s, box-shadow 0.2s;
}

.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.btn:active {
  transform: translateY(0);
}

.btn-increment {
  background-color: #4caf50;
  color: white;
}
// ...

6. Things to Consider

Best Practices:

  • State Updates: Use functional updates when new state depends on previous state:
    text
    setCount(prevCount => prevCount + 1)
  • Initial Value: Consider making the initial count configurable via props
  • Boundaries: Add minimum/maximum limits if needed
  • Accessibility: Add proper ARIA labels for screen readers
  • Performance: For this simple component, performance is not a concern

Common Pitfalls:

  • Don't mutate state directly:
    text
    count++
    won't work
  • Don't forget to import
    text
    useState
    from React
  • Ensure event handlers are properly bound to buttons

Enhancements:

  • Add step value (increment/decrement by custom amount)
  • Add keyboard shortcuts
  • Persist counter value to localStorage
  • Add animations for count changes
  • Implement min/max boundaries
  • Add custom increment value input

Example with Functional Updates:

jsx
const increment = () => {
  setCount(prevCount => prevCount + 1);
};

const decrement = () => {
  setCount(prevCount => prevCount - 1);
};

Example with Props for Initial Value:

jsx
function Counter({ initialValue = 0 }) {
  const [count, setCount] = useState(initialValue);
  
  // ... rest of the code
}

Testing Considerations:

  • Test increment functionality
  • Test decrement functionality
  • Test reset functionality
  • Test initial state rendering
  • Test multiple rapid clicks

This counter component serves as a foundational exercise for understanding React state management and forms the basis for more complex interactive components.

No files open

Click a file in the explorer to view