useDeepCompareEffect
A modified useEffect hook that is using deep comparison on its dependencies instead of reference equality
useDeepCompareEffect is a drop-in replacement for useEffect that performs deep structural comparison on the dependency array instead of shallow reference checks. This prevents unnecessary effect executions when dependencies are new object or array references that contain the same values. It has the same signature as useEffect and supports cleanup functions.
When to Use
- When your effect depends on objects or arrays that are re-created on every render (e.g., inline objects, API response data)
- Avoiding infinite effect loops caused by non-memoized dependency references
- When
useMemooruseCallbackon every dependency would be overly verbose
Notes
- Performance: Deep comparison has overhead proportional to the size of the dependency values. For large or deeply nested objects, consider
useCustomCompareEffectwith a targeted comparator instead. - Cleanup support: Supports return-based cleanup functions identically to
useEffect. - See also
useCustomCompareEffectwhen you need comparison logic beyond deep equality.
Usage
Live Editor
function Demo() { const [count, setCount] = useState(0); const effectCountRef = useRef(0); const deepCompareCountRef = useRef(0); useEffect(() => { effectCountRef.current += 1; // eslint-disable-next-line react-hooks/exhaustive-deps }, [{}]); useDeepCompareEffect(() => { deepCompareCountRef.current += 1; return () => { // do something }; }, [{}]); return ( <div> <p>effectCount: {effectCountRef.current}</p> <p>deepCompareCount: {deepCompareCountRef.current}</p> <p> <button type="button" onClick={() => setCount(c => c + 1)}> reRender </button> </p> </div> ); };
Result
API
useDeepCompareEffect
Returns
void
Arguments
| Argument | Description | Type | DefaultValue |
|---|---|---|---|
| effect | effect function | React.EffectCallback (Required) | - |
| deps | dep list | React.DependencyList (Required) | - |