React useMutationObserver Hook
index.html
and script.js
have already been provided in the VM. In general, you only need to add code to script.js
and style.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
, and options
.
- Inside the hook, a
useEffect()
hook is used that depends on the values of callback
and options
.
- If the given
ref
is initialized, a new MutationObserver
is created and passed the callback
.
MutationObserver.observe()
is called with the given options
to watch the given ref
for changes.
MutationObserver.disconnect()
is used to remove the observer from the ref
when 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.