Kritim Yantra
Aug 06, 2025
Ever built a React app where passing data between components felt like playing a never-ending game of telephone? You start with a simple useState, but before you know it, you’re passing props through five different components just to update a single button.
Sound familiar? You’re not alone.
State management is one of the biggest pain points for new React developers. But here’s the good news: it doesn’t have to be complicated.
In this guide, we’ll break down the best ways to manage state in React—from simple useState to powerful tools like Redux and Zustand. By the end, you’ll know exactly which approach to use for your next project.
useState (Good for Small Apps)When you just need to track a single piece of data (like a counter or form input), useState is your best friend.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me!
</button>
</div>
);
}
✅ Best for:
❌ Not great for:
useReducer (When useState Gets Messy)If your component has complex state logic (like a form with multiple fields or a shopping cart), useReducer keeps things clean.
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
✅ Best for:
❌ Not great for:
dispatch around)useContextTired of passing props through 10 components just to update a theme? useContext lets you share state globally.
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
function App() {
return (
<ThemeProvider>
<Header />
<MainContent />
</ThemeProvider>
);
}
function Header() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<header className={theme}>
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
</header>
);
}
✅ Best for:
❌ Not great for:
Redux is the go-to for large-scale apps (think Facebook, Airbnb). It keeps state in a central store and updates it predictably.
npm install @reduxjs/toolkit react-redux
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => { state.value += 1 },
decrement: (state) => { state.value -= 1 },
},
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
const store = configureStore({
reducer: {
counter: counterReducer,
},
});
import { Provider, useSelector, useDispatch } from 'react-redux';
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
</div>
);
}
✅ Best for:
❌ Not great for:
If Redux feels too heavy, try Zustand—a lightweight state management library.
npm install zustand
import { create } from 'zustand';
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));
function Counter() {
const { count, increment, decrement } = useCounterStore();
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}
✅ Best for:
❌ Not great for:
| Tool | Best For | Learning Curve | Performance |
|---|---|---|---|
useState |
Small components | Easy | Great |
useReducer |
Complex state | Medium | Great |
useContext |
Global settings | Medium | Good (avoid frequent updates) |
| Redux | Large apps | Steep | Optimized |
| Zustand | Medium apps | Easy | Very Good |
useState and useContext. What’s your biggest struggle with state management?
👉 Drop a comment below—I’d love to help!
Happy coding! 🚀
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google
Kritim Yantra
Kritim Yantra
Kritim Yantra