React useMutationObserver hook
React, Hooks, Effect · Nov 23, 2021

Watches for changes made to the DOM tree, using a MutationObserver
- Use a
useEffect()
hook that depends on the values ofcallback
andoptions
. - Check if the given
ref
is initialized. If it is, create a newMutationObserver
and pass it thecallback
. - Call
MutationObserver.observe()
with the givenoptions
to watch the givenref
for changes. - Use
MutationObserver.disconnect()
to remove the observer from theref
when the component unmounts.
const useMutationObserver = (
ref,
callback,
options = {
attributes: true,
characterData: true,
childList: true,
subtree: true,
}
) => {
React.useEffect(() => {
if (ref.current) {
const observer = new MutationObserver(callback);
observer.observe(ref.current, options);
return () => observer.disconnect();
}
}, [callback, options]);
};
const App = () => {
const mutationRef = React.useRef();
const [mutationCount, setMutationCount] = React.useState(0);
const incrementMutationCount = () => {
return setMutationCount(mutationCount + 1);
};
useMutationObserver(mutationRef, incrementMutationCount);
const [content, setContent] = React.useState('Hello world');
return (
<>
<label for="content-input">Edit this to update the text:</label>
<textarea
id="content-input"
style={{ width: '100%' }}
value={content}
onChange={e => setContent(e.target.value)}
/>
<div
style={{ width: '100%' }}
ref={mutationRef}
>
<div
style={{
resize: 'both',
overflow: 'auto',
maxWidth: '100%',
border: '1px solid black',
}}
>
<h2>Resize or change the content:</h2>
<p>{content}</p>
</div>
</div>
<div>
<h3>Mutation count {mutationCount}</h3>
</div>
</>
);
};
ReactDOM.createRoot(document.getElementById('root')).render(
<App />
);
Written by Angelos Chalaris
I'm Angelos Chalaris, a JavaScript software engineer, based in Athens, Greece. The best snippets from my coding adventures are published here to help others learn to code.
If you want to keep in touch, follow me on GitHub.