State in React Components: Beginner’s Guide with Examples
In React, state represents the data of a component.
It decides what the UI looks like at any given time.
When state changes, the component re-renders automatically.
Think of state as a memory for your component.
Example: If you build a counter app, the number is stored in state.
Props vs State (Quick Recap)
| Feature | Props | State |
|---|---|---|
| Definition | Data passed from parent → child | Data managed inside component |
| Read/Write | Read-only | Read & write (mutable) |
| Who controls it? | Parent component | Component itself |
| Use case | Customize child components | Store changing data (like form inputs, counters) |
State in Functional Components (with Hooks)
Modern React uses Hooks (especially useState) for state management in functional components.
Example: Counter with useState
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0); // initial state = 0
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
<button onClick={() => setCount(count - 1)}>Decrease</button>
</div>
);
}
count= current state valuesetCount= function to update stateUpdating state causes the component to re-render
State in Class Components
Before Hooks, state was managed with class components using this.state and this.setState().
Example: Counter in Class Component
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 }; // initial state
}
increase = () => {
this.setState({ count: this.state.count + 1 });
};
decrease = () => {
this.setState({ count: this.state.count - 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increase}>Increase</button>
<button onClick={this.decrease}>Decrease</button>
</div>
);
}
}
Multiple State Variables
You can manage multiple state variables inside a component.
function Profile() {
const [name, setName] = useState("John");
const [age, setAge] = useState(25);
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
<button onClick={() => setAge(age + 1)}>Increase Age</button>
</div>
);
}
Updating State Correctly
State updates in React are asynchronous.
If you update state based on the previous value, use a function inside setState/setCount.
setCount(prevCount => prevCount + 1); This ensures updates are correct even if multiple state changes happen at once.
Best Practices for State
Keep state minimal – only store data that changes.
Don’t store everything in state (e.g., computed values).
Store only the changing data.Use local state for small components (e.g., forms, toggles).
Lift state up when multiple components need the same data.
For complex apps → use external libraries (Redux, Zustand, Recoil, Context API).
Example: Form with State
function Form() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
alert(`Name: ${name}, Email: ${email}`);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Enter name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<input
type="email"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
);
}
Here, the form fields are stored in component state.
FAQ
Q1: Can I modify state directly like state.count = 5?
No. You must use setState or setCount to trigger re-renders.
Q2: Should I use state for every variable?
No. Use state only for dynamic, changing data.
Q3: Is useState better than class-based state?
Yes. Functional components with Hooks are the modern standard.