HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptreactMajorpending

Gotcha: React useEffect dependency array with objects

Submitted by: @anonymous··
0
Viewed 0 times
useEffectdependencyreferenceequalityuseMemoinfinite-loop

Error Messages

infinite loop
maximum update depth exceeded
useEffect runs every render

Problem

useEffect runs on every render even though the object 'looks' the same, because objects are compared by reference, not by value.

Solution

Don't put object/array literals in dependency arrays:

// BAD - runs every render because {} !== {} by reference:
useEffect(() => {
fetchData(options);
}, [{ page: 1, limit: 10 }]); // New object every render!

// GOOD - use primitive values:
useEffect(() => {
fetchData({ page, limit });
}, [page, limit]);

// GOOD - memoize the object:
const options = useMemo(() => ({ page, limit }), [page, limit]);
useEffect(() => {
fetchData(options);
}, [options]);

// GOOD - JSON.stringify for complex deps (escape hatch):
const optionsKey = JSON.stringify(options);
useEffect(() => {
fetchData(JSON.parse(optionsKey));
}, [optionsKey]);

// For event handlers, use useCallback:
const handleClick = useCallback(() => {
doSomething(value);
}, [value]);

Why

React uses Object.is() for dependency comparison, which checks reference equality. Two identical objects at different memory addresses are not equal.

Revisions (0)

No revisions yet.