Introduction
In this lab, we will learn how to use the useMutationObserver hook in React to watch for changes made to the DOM tree using a MutationObserver. The hook allows us to specify a callback function to be executed when a change is observed, and we can also provide options to customize the observer's behavior. Through this lab, we will be able to understand how to implement the useMutationObserver hook in our React applications.
React useMutationObserver Hook
index.htmlandscript.jshave already been provided in the VM. In general, you only need to add code toscript.jsandstyle.css.
To watch changes made to the DOM tree, the useMutationObserver hook can be used. Here's how it works:
- The hook takes in three parameters:
ref,callback, andoptions. - Inside the hook, a
useEffect()hook is used that depends on the values ofcallbackandoptions. - If the given
refis initialized, a newMutationObserveris created and passed thecallback. MutationObserver.observe()is called with the givenoptionsto watch the givenreffor changes.MutationObserver.disconnect()is used to remove the observer from therefwhen the component unmounts.
Here's the code:
const useMutationObserver = (
ref,
callback,
options = {
attributes: true,
characterData: true,
childList: true,
subtree: true
}
) => {
React.useEffect(() => {
if (!ref.current) return;
const observer = new MutationObserver(callback);
observer.observe(ref.current, options);
return () => observer.disconnect();
}, [callback, options, ref]);
};
In the App component, the useMutationObserver hook is used to watch for changes made to the mutationRef element. The incrementMutationCount function is passed as the callback.
const App = () => {
const mutationRef = React.useRef();
const [mutationCount, setMutationCount] = React.useState(0);
const incrementMutationCount = React.useCallback(() => {
setMutationCount((count) => count + 1);
}, []);
useMutationObserver(mutationRef, incrementMutationCount);
const [content, setContent] = React.useState("Hello world");
return (
<>
<label htmlFor="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 />);
Please click on 'Go Live' in the bottom right corner to run the web service on port 8080. Then, you can refresh the Web 8080 Tab to preview the web page.
Summary
Congratulations! You have completed the React useMutationObserver Hook lab. You can practice more labs in LabEx to improve your skills.