a computer screen with a logo on it

Understanding React State: Building a Simple Counter Component

4 minutes read

React is a powerful JavaScript library for building user interfaces, and one of its core features is state management. In this tutorial, we'll create a simple counter component to understand how React state works.

Prerequisites

  • Basic knowledge of HTML, CSS, and JavaScript
  • Node.js installed on your computer
  • A code editor (like VS Code)

What We'll Build

We'll create a counter component with three buttons:

  • Decrease: reduces the count by 1
  • Reset: sets the count back to 0
  • Increase: adds 1 to the count

Step 1: Setting Up Your React Project

First, create a new React project using Create React App:

# Create a new React project
npx create-react-app my-counter-app --template typescript

# Move into the project directory
cd my-counter-app

# Start the development server
npm start

Step 2: Clean Up the Initial Files

First, let's clean up the default files. Go to src/App.tsx and replace everything with this basic structure:

import Reactive from './components/Reactive';

function App() {
return (
<div className="App">
<Reactive title="React State Demo"/>
</div>
);
}

export default App;

Step 3: Creating the Counter Component

Add the css file to App.css:

.counter-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 300px;
padding: 24px;
background-color: white;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.counter-title {
font-size: 24px;
font-weight: bold;
color: #1f2937;
margin-bottom: 16px;
}

.counter-value {
font-size: 60px;
font-weight: bold;
color: #2563eb;
margin-bottom: 32px;
}

.button-container {
display: flex;
gap: 16px;
}

.button {
padding: 8px 16px;
border: none;
border-radius: 6px;
color: white;
font-size: 16px;
cursor: pointer;
transition: background-color 0.2s;
}

.decrease-button {
background-color: #ef4444;
}

.decrease-button:hover {
background-color: #dc2626;
}

.reset-button {
background-color: #6b7280;
}

.reset-button:hover {
background-color: #4b5563;
}

.increase-button {
background-color: #22c55e;
}

.increase-button:hover {
background-color: #16a34a;
}

Then create a new folder Components in your react project and inside the folder add new file Reactive.tsx containing the function component:

import '../../App.css';
import { useState } from "react";

export default function Reactive({title}:{title:string}) {
const [count, setCount] = useState(0);

return (
<div className="counter-container">
<h2 className="counter-title">{title || "React State Demo"}</h2>

<div className="counter-value">{count}</div>

<div className="button-container">
<button
onClick={() => setCount(prev => prev - 1)}
className="button decrease-button"
>
Decrease
</button>

<button
onClick={() => setCount(0)}
className="button reset-button"
>
Reset
</button>

<button
onClick={() => setCount(prev => prev + 1)}
className="button increase-button"
>
Increase
</button>
</div>
</div>
);
}

Let's Break Down the Code

1. Importing Dependencies

import '../../App.css';
import { useState } from "react";

2. Component Definition

export default function Reactive()

We create a function component

3. State Management

React state is like a component's memory. It allows components to keep track of changing data. When state changes, React automatically re-renders the component.

The useState hook is how we create state variables in functional components:

const [count, setCount] = useState(0);

This line does two things:

  • Creates a state variable called count initialized to 0
  • Provides a function setCount to update this value

This creates our state variable and its updater function.

4. Event Handlers

We have three different ways to update state:

// Decrease: Using previous state
onClick={() => setCount(prev => prev - 1)}

// Reset: Setting direct value
onClick={() => setCount(0)}

// Increase: Using previous state
onClick={() => setCount(prev => prev + 1)}

Note: When updating state based on the previous state, always use the callback form (prev => prev + 1) to ensure you're working with the most current value.

Key Concepts Learned

  • useState Hook: Used to add state management to functional components
  • State Updates: How to modify state using the setter function
  • Previous State: How to update state based on its previous value
  • Event Handling: How to respond to user interactions
  • Conditional Rendering: Using props with fallback values (title || "React State Demo")

Run the application

Your application will look like this

React State Demo

0

Conclusion

You've just built a simple but functional React component that demonstrates core concepts like:

  • State management with hooks
  • Event handling
  • Component props
  • Conditional rendering

This foundation will help you understand more complex React patterns and build more sophisticated applications.

Next Steps

  • Try adding a minimum and maximum value for the counter
  • Add input field to set a custom value
  • Implement a delay or animation when changing the number
  • Add localStorage to persist the count between page refreshes

Happy coding! 🚀

Share this article

Related Articles