Go to all posts

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 Common Mistakes

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! 🚀