Understanding React State Management
Go Home
State management is one of the most important concepts in React. Let’s explore different approaches with practical examples.
Local State with useState#
The simplest form of state management is local component state using the useState hook.
Counter Example
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
const [step, setStep] = useState(1)
return (
<div>
<h4>Counter: {count}</h4>
<button onClick={() => setCount(count - step)}>
- {step}
</button>
<button onClick={() => setCount(0)}>
Reset
</button>
<button onClick={() => setCount(count + step)}>
+ {step}
</button>
<input
type="number"
value={step}
onChange={(e) => setStep(Number(e.target.value))}
placeholder="Step size"
/>
</div>
)
}When to Use Local State#
Local state is perfect when:
- State is only used within a single component
- State doesn’t need to be shared with siblings
- The component is relatively simple
function SearchBar() {
const [query, setQuery] = useState('')
return (
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
)
}Props Drilling Problem#
When you need to pass state through multiple levels, it becomes cumbersome:
function App() {
const [user, setUser] = useState(null)
return <Layout user={user} setUser={setUser} />
}
function Layout({ user, setUser }) {
return <Header user={user} setUser={setUser} />
}
function Header({ user, setUser }) {
return <UserProfile user={user} setUser={setUser} />
}Context API Solution#
For app-wide state, Context API is built into React:
import { createContext, useContext, useState } from 'react'
const UserContext = createContext()
export function UserProvider({ children }) {
const [user, setUser] = useState(null)
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
)
}
export function useUser() {
return useContext(UserContext)
}
// Usage
function UserProfile() {
const { user, setUser } = useUser()
return <div>{user?.name}</div>
}When to Use External Libraries#
Consider Redux, Zustand, or Jotai when:
- You have complex state logic
- You need time-travel debugging
- Multiple components need to access and modify the same state
- You want better DevTools integration
Conclusion#
Start with local state, use Context for app-wide state, and only reach for external libraries when you truly need them. React’s built-in tools are powerful enough for most applications!