useDeepCompareEffect
Runs an effect when a dependency array changes by deep equality.
About
useDeepCompareEffect has the cleanup semantics of useEffect, but retains the previous dependency array while fast-deep-equal considers the next array equal. Use it for structural object dependencies that cannot be stabilized at their source.
Examples
import { useState } from "react";
import { useDeepCompareEffect } from "rooks";
export default function FilterSummary() {
const [page, setPage] = useState(1);
const filters = { page, sort: "name" };
const [summary, setSummary] = useState("");
useDeepCompareEffect(() => {
setSummary(`Page ${filters.page}, sorted by ${filters.sort}`);
}, [filters]);
return (
<section>
<p>{summary}</p>
<button type="button" onClick={() => setPage((value) => value + 1)}>
Next page
</button>
</section>
);
}Parameters
| Argument | Type | Default | Meaning |
|---|---|---|---|
callback | EffectCallback | required | React effect callback; it may return cleanup. |
dependencies | DependencyList | required | Array compared structurally between renders. |
Passing a non-array value throws. An array containing only primitive values emits a development warning because ordinary useEffect is cheaper for that case.
Return value
The hook returns void.
Behavior and lifecycle
The effect runs after commit on mount and whenever the dependency array is not deeply equal to the previous retained array. React runs the prior cleanup before a changed effect and on unmount. Deep comparison happens during render and can be expensive for large or cyclic structures; fast-deep-equal does not make arbitrary cyclic graphs safe.
Compatibility and accessibility
No browser API is required, so the hook is safe to render on the server. Effects still do not run until the client commits. Accessibility depends on the side effect; avoid silently moving focus or changing visible state without an appropriate announcement.