In React, you usually don’t need to interact directly with the DOM, but sometimes you may need to track changes like when elements are added or removed. This is where MutationObserver comes in. It helps you monitor changes to the DOM and respond to them.
What is MutationObserver?
MutationObserver is a JavaScript API that lets you watch for changes in the DOM. You can track :
- childList - When elements are added or removed.
- attributes - When element properties (like class or style) change.
- subtree - Changes to any part of the node tree.
- characterData - Changes in the text content of a node.
Using MutationObserver in React
Let’s create a React component that uses MutationObserver
to detect when products are added to a list.
import React, { useEffect, useRef, useState } from 'react';
const ProductMutationObserver = () => {
const containerRef = useRef(null);
const [products, setProducts] = useState([]);
useEffect(() => {
const container = containerRef.current;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
console.log('mutation detected :', mutation);
});
});
observer.observe(container, {
childList: true,
subtree: true,
});
return () => observer.disconnect();
}, []);
const handleAddProduct = () => {
setProducts((prevProducts) => [
...prevProducts,
`Product ${prevProducts.length + 1} added`,
]);
};
return (
<div>
<button onClick={handleAddProduct}>Add Product</button>
<div ref={containerRef}>
<p>Product List :</p>
<ul>
{products.map((product, index) => (
<li key={index}>{product}</li>
))}
</ul>
</div>
</div>
);
};
export default ProductMutationObserver;
How It Works
- The
containerRef
- This is how we get a reference to the DOM element that holds our product list. We useuseRef
to create the reference. - Setting up the MutationObserver - In the
useEffect
hook, we set up the MutationObserver to monitor changes to the DOM. We’re looking specifically for changes to the child elements (like when a new product is added) and any changes in the subtree (which means all nested child elements). - Adding Products - The
handleAddProduct
function adds a new product to the list when the button is clicked. Every time the list changes, MutationObserver will detect the update and log the mutation. - Clean Up - We make sure to disconnect the observer when the component is unmounted to avoid memory leaks.
Why Use MutationObserver in React?
- Third-party libraries - If a library manipulates the DOM outside React, MutationObserver helps track these changes.
- Dynamic content - For apps where content changes dynamically (like chat apps), it’s useful for tracking updates.
- Performance - It can be more efficient than constantly checking for changes or re-rendering components.
Conclusion
While React manages most DOM updates, MutationObserver is helpful for tracking changes outside React’s control. It allows you to respond to DOM changes efficiently and improve your app's interactivity.