Common Mistakes with useState and useEffect in React
Dipesh Aryal/June 13, 2025
Learn to avoid frequent pitfalls when using useState and useEffect with practical fixes and patterns.
React Hooks like useState
and useEffect
are powerful—but it's easy to misuse them. Here's a list of common pitfalls and how to fix them effectively.
🧠 1. Batching State Updates Incorrectly
setCount(count + 1)
setCount(count + 1) // Not what you expect!
✅ Fix: Use Functional Update
setCount((prev) => prev + 1)
setCount((prev) => prev + 1)
🔁 2. Conditionally Calling Hooks
if (something) {
useEffect(() => {
// ❌ Illegal hook call
}, [])
}
✅ Fix: Hooks Must Be Called Unconditionally
useEffect(() => {
if (something) {
// ✅ safe
}
}, [])
🔧 3. Directly Mutating State Objects
state.user.name = 'New Name'
setUser(state.user)
✅ Fix: Use Spread Operator
setUser((prev) => ({
...prev,
name: 'New Name',
}))
🧮 4. Derived State in useState
const [fullName, setFullName] = useState(firstName + ' ' + lastName)
✅ Fix: Just Compute It
const fullName = `${firstName} ${lastName}`
No need to store derived values in state—compute them from source values directly.
❌ 5. Component Not Rerendering
Calling a setter like setCount(5)
when count
is already 5
won't cause a re-render. But with objects, things behave differently:
setUser({ ...user }) // will trigger rerender if ref changes
To ensure useEffect
tracks object changes correctly:
useEffect(() => {
// do something
}, [user.id]) // use primitive key inside object
🛠️ 6. Not Using Custom Hooks
Utility functions ≠ Custom Hooks
Custom hooks encapsulate logic using other hooks like useState
, useEffect
, useContext
.
✅ Example
function useLocalStorage(key, initial) {
const [value, setValue] = useState(() => {
return localStorage.getItem(key) || initial
})
useEffect(() => {
localStorage.setItem(key, value)
}, [key, value])
return [value, setValue]
}
Now reuse it in any component:
const [theme, setTheme] = useLocalStorage('theme', 'dark')
✅ Conclusion
Understanding how useState
and useEffect
behave helps you write more predictable, optimized components. Avoiding these common mistakes and using patterns like derived state and custom hooks can greatly clean up your code.
Happy coding! 🚀