State is the memory of a React component. It allows interactive applications to re-render in response to user input, network responses, or timer ticks. React provides two primary state management hooks: `useState` for independent values and `useReducer` for complex state transitions.
1. `useState` Basics & Functional Updaters
const [count, setCount] = useState(0);
// Functional updater prevents stale state bugs during rapid clicks
setCount(prevCount => prevCount + 1);
// Functional updater prevents stale state bugs during rapid clicks
setCount(prevCount => prevCount + 1);
2. When to Switch to `useReducer`?
Use useReducer when state logic involves multiple sub-values or when the next state depends on the previous state in complex ways (e.g., shopping cart operations).
3. Live Code Example: Shopping Cart with `useReducer`
import React, { useReducer } from 'react';
// 1. Reducer Pure Function
function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM':
return { ...state, items: [...state.items, action.payload] };
case 'REMOVE_ITEM':
return { ...state, items: state.items.filter(item => item.id !== action.payload) };
case 'CLEAR_CART':
return { ...state, items: [] };
default:
return state;
}
}
export default function ShoppingCart() {
const [cart, dispatch] = useReducer(cartReducer, { items: [] });
return (
<div className="p-4 border rounded">
<h4>Shopping Cart Items ({cart.items.length})</h4>
<button
className="btn btn-primary mb-3"
onClick={() => dispatch({ type: 'ADD_ITEM', payload: { id: Date.now(), name: 'React 19 Book', price: 29.99 } })}
>
Add Book to Cart
</button>
<ul className="list-group mb-3">
{cart.items.map(item => (
<li key={item.id} className="list-group-item d-flex justify-content-between">
{item.name} - ${item.price}
<button className="btn btn-sm btn-danger" onClick={() => dispatch({ type: 'REMOVE_ITEM', payload: item.id })}>Remove</button>
</li>
))}
</ul>
</div>
);
}
// 1. Reducer Pure Function
function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM':
return { ...state, items: [...state.items, action.payload] };
case 'REMOVE_ITEM':
return { ...state, items: state.items.filter(item => item.id !== action.payload) };
case 'CLEAR_CART':
return { ...state, items: [] };
default:
return state;
}
}
export default function ShoppingCart() {
const [cart, dispatch] = useReducer(cartReducer, { items: [] });
return (
<div className="p-4 border rounded">
<h4>Shopping Cart Items ({cart.items.length})</h4>
<button
className="btn btn-primary mb-3"
onClick={() => dispatch({ type: 'ADD_ITEM', payload: { id: Date.now(), name: 'React 19 Book', price: 29.99 } })}
>
Add Book to Cart
</button>
<ul className="list-group mb-3">
{cart.items.map(item => (
<li key={item.id} className="list-group-item d-flex justify-content-between">
{item.name} - ${item.price}
<button className="btn btn-sm btn-danger" onClick={() => dispatch({ type: 'REMOVE_ITEM', payload: item.id })}>Remove</button>
</li>
))}
</ul>
</div>
);
}
Learn State Management at Telugu IT Tutorials
Master React state, Redux Toolkit, and Zustand in our live full-stack developer training programs. View Courses →