Back to TIL
March 2026
posted on 03.28.2026

React useMemo Prevents Infinite useEffect Loops

Deriving an array with .map() inside a component body creates a new array reference on every render, even if the contents are identical. If that array is in a useEffect dependency list, it triggers an infinite loop.

// BAD: entries is a new array every render, useEffect fires forever
const entries = entriesWithContent.map(e => e.entry)

useEffect(() => {
  fetchReactions(entries)
}, [entries]) // new reference every render = infinite loop
// GOOD: useMemo stabilizes the reference
const entries = useMemo(
  () => entriesWithContent.map(e => e.entry),
  [entriesWithContent]
)

useEffect(() => {
  fetchReactions(entries)
}, [entries]) // only fires when entriesWithContent actually changes

This applies to any derived value in a dependency array: .filter(), .reduce(), Object.keys(), spread into new object, etc. If it creates a new reference, wrap it in useMemo.

React's comparison is referential (Object.is), not structural. Two arrays with identical contents are still different objects.

No reactions yet

in Naperville, IL
Last visitor from Mitaka, Japan