useMutationObserver
Layout & observersWatch an element for DOM mutations — child, attribute, and character-data changes — with the MutationObserver API
Install
$ npm install @usefy/use-mutation-observerQuick start
import { useMutationObserver } from "@usefy/use-mutation-observer";
function Watched() {
const { ref, records } = useMutationObserver<HTMLDivElement>({
childList: true,
subtree: true,
onMutation: (mutations) => {
for (const m of mutations) console.log(m.type, m.target);
},
});
return <div ref={ref}>{records.length} recent mutations</div>;
}API reference
useMutationObserver<T>(options?)
Observes the element attached via the returned ref for DOM mutations.
Options — UseMutationObserverOptions<T>
| Option | Type | Default | Description |
|---|---|---|---|
childList | boolean | true* | Observe additions/removals of the target's child nodes |
attributes | boolean | false | Observe attribute changes (implied true when attributeFilter/attributeOldValue is set) |
attributeFilter | string[] | — | Only observe the named attributes (implies attributes: true) |
attributeOldValue | boolean | false | Record the previous attribute value in MutationRecord.oldValue (implies attributes) |
characterData | boolean | false | Observe character-data changes |
characterDataOldValue | boolean | false | Record the previous character data in oldValue (implies characterData) |
subtree | boolean | false | Extend observation to the whole subtree, not just direct children |
onMutation | (mutations: MutationRecord[], observer: MutationObserver) => void | — | Callback fired with each batch of records (stored in a ref — safe to pass inline) |
enabled | boolean | true | When false, disconnects and stops reporting; flip back to true to re-observe |
updateState | boolean | true | Whether to mirror the latest batch into the records state. false = callback-only |
* childList defaults to true only when none of childList/attributes/characterData is enabled — the DOM API requires at least one.
Returns — UseMutationObserverReturn<T>
| Property | Type | Description |
|---|---|---|
ref | (element: T | null) => void | Callback ref to attach to the target; null disconnects |
records | readonly MutationRecord[] | The latest batch of records (empty until the first mutation) |
isSupported | boolean | Whether the MutationObserver API is available |
isObserving | boolean | Whether the hook is currently observing an element |
observe | (element: T) => void | Manually start observing an element (escape hatch alongside ref) |
disconnect | () => void | Disconnect the observer, stopping all observation |
takeRecords | () => MutationRecord[] | Flush and return any queued-but-undelivered records |
Note:
MutationObserverhas no per-targetunobserve;disconnect()(dropping all observation) is the only way to stop, matching the native API.
disconnect()is terminal: after calling it, re-attaching the samerefdoes not restart observation (the ref only re-observes when the element changes, and the internal observer is torn down). To resume, callobserve(element)again, or remount the component.
Also exported: isMutationObserverSupported() and resolveMutationConfig(options) (pure helpers), the EMPTY_RECORDS sentinel, and the UseMutationObserverOptions, UseMutationObserverReturn, OnMutationCallback types.
Go deeper
This page is the quick reference. For every example, prop, and edge case, read the full README — or open Storybook to change props live.