State is data that belongs to a component and can change over time. When state changes, React can render the component again so the UI reflects the new state.
1 Why Do We Need State?
Normal JavaScript variables do not provide React with a mechanism for updating the rendered UI when their values change.
function Counter() {
let count = 0;
function increase() {
count++;
}
return (
<button onClick={increase}>
{count}
</button>
);
}
Changing count here does not tell React that it should render the new value. React state solves this problem.
2 useState
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
useState returns two values:
- The current state value.
- A setter function used to request a state update.
3 State Update Flow
flowchart TD
A[User Clicks Button] --> B[State Setter Called]
B --> C[React Schedules Update]
C --> D[Component Renders Again]
D --> E[New State Available]
E --> F[UI Shows New Value]
4 State Is Local by Default
State created by useState belongs to that component instance. If two components each call useState, they normally have separate state.
5 Functional State Updates
When the next value depends on the previous value, use the functional updater form.
setCount(previous => previous + 1);
This clearly tells React that the new value should be calculated from the previous state.
6 Updating Objects
State objects should normally be replaced rather than directly mutated.
const [user, setUser] = useState({
name: "Rahul",
age: 30
});
setUser(previous => ({
...previous,
age: 31
}));
7 Updating Arrays
const [items, setItems] = useState([]);
function addItem(item) {
setItems(previous => [
...previous,
item
]);
}
function removeItem(id) {
setItems(previous =>
previous.filter(item => item.id !== id)
);
}
8 Complete Example — Shopping Cart
import { useState } from "react";
function ShoppingCart() {
const [cart, setCart] = useState([]);
function addProduct(product) {
setCart(previous => [
...previous,
product
]);
}
function removeProduct(productId) {
setCart(previous =>
previous.filter(
product => product.id !== productId
)
);
}
const products = [
{ id: 1, name: "Laptop", price: 75000 },
{ id: 2, name: "Phone", price: 40000 }
];
return (
<div>
<h2>Products</h2>
{products.map(product => (
<button
key={product.id}
onClick={() => addProduct(product)}
>
Add {product.name}
</button>
))}
<h2>Cart: {cart.length}</h2>
{cart.map(product => (
<div key={product.id}>
{product.name}
<button
onClick={() =>
removeProduct(product.id)
}
>
Remove
</button>
</div>
))}
</div>
);
}
9 Multiple State Variables
A component can have multiple independent state values.
const [name, setName] = useState("");
const [age, setAge] = useState(0);
const [isActive, setIsActive] = useState(false);
Separate state variables can be useful when the values are logically independent.
10 State vs Normal Variables
| Normal Variable | React State |
|---|---|
| Does not notify React when changed | Setter tells React about an update |
| Value does not persist as component state across renders in the same way | React preserves state between renders |
| Not intended to control rendered UI | Can control rendered UI |
11 Derived Data
Not every value needs its own state. If a value can be calculated from existing state or props, it is often better to calculate it.
const [price, setPrice] = useState(1000);
const [quantity, setQuantity] = useState(2);
const total = price * quantity;
There is usually no need for another state variable called total if it can always be calculated from price and quantity.
12 State Updates Are Not Direct Mutation
// Incorrect
user.age = 31;
// Correct
setUser(previous => ({
...previous,
age: 31
}));
13 Common Mistakes
- Mutating state directly.
- Using a normal variable when the UI needs to react to changes.
- Duplicating derived data in state.
- Forgetting the functional updater when the next state depends on previous state.
- Putting unrelated data into one very large state object.
14 Interview Questions
- What is state in React?
- Why do we use useState?
- What does useState return?
- Why should state not be mutated directly?
- When should you use a functional state update?
- How do you update an object in state?
- How do you add and remove items from a state array?
- Can a component have multiple state variables?
- What is derived state?
15 Key Takeaways
- State stores changing data that affects the UI.
useStateprovides state to function components.- Use the setter to update state.
- Use functional updates when the next value depends on the previous value.
- Update objects and arrays without direct mutation.
- Avoid storing values that can be calculated from existing data.
Conclusion
State is one of the most important React concepts. Once you understand that state represents changing UI data and that a state update causes React to render using the new value, many React concepts become much easier to understand.