MutationObserver
Tags: javascript, react, mutationobserver
Published: 2023-03-23 08:54:50

## What is the mutation observer?

**MutationObserver** is a JavaScript API that allows developers to listen for changes to specific elements or nodes in the DOM (Document Object Model). It provides a way to observe and respond to changes that occur within the DOM structure.

The MutationObserver works by registering a callback function to observe a specific target element or node in the DOM. When a change occurs, such as a node being added or removed, the callback function is called with a list of MutationRecord objects that describe the changes that have occurred.

The MutationObserver API provides a powerful tool for building responsive web applications that need to react to changes in the DOM. It can be used to implement a wide range of features, such as lazy-loading content, auto-updating UI elements, and real-time data synchronization.


---

Let me explain **mutation observer** through an example.

Our aim is to add an animation when the category's section height changes. We need to listen that operation

| before | after|
|--------|------|
| ![before](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hg7cyyy56am122lh78fb.gif) | ![after](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/872exw8nr79zw8xfemud.gif)|

In order to do this we need a reference of the category section.

```react
import React, { useRef } from 'react';
import { CategoryItems } from './category-items/category-items';
import { CategoryTitles } from './category-titles/category-titles';
import './categories.scss';

const Categories = () => {
  const categoriesRef = useRef<HTMLDivElement>(null);

  return (
    <div className="categories" ref={categoriesRef}>
      <CategoryTitles />
      <CategoryItems />
    </div>
  );
};

export { Categories };

```

After preparing the `categoriesRef`, we can create the **`mutationObserver`** structure.

First of all, we need to create mutationObserver 

```js
  const mutationObserver = new MutationObserver(async () => {
    console.log('mutationObserver operation');
  });
```

This is our mutationObserver instance we will call this instance from `useEffect` 


```js
  useEffect(() => {
    if (categoriesRef.current) {
      mutationObserver.observe(categoriesRef.current, {
        childList: true,
        subtree: true,
      });

      return () => {
        mutationObserver.disconnect();
      };
    }
  }, []);
```  

- We defined `mutationObserver.observe` with `categoriesRef.current` which listens to the **parameters** such as `childList` and `subtree`, also you can check [this](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#parameters) out for more parameters.

- And also we define the `mutationObserver.disconnect()` on **componentWillUnmount** hook for delete listen operation when component closed.


Henceforward when the height change at `categoriesRef` we will see the console log.

```js
    console.log('mutationObserver operation');
```

Then we will add the animation handler code piece and define a CSS transition to `categoriesRef`

```js
  const mutationObserver = new MutationObserver(async () => {
    const categoryTitles = document.getElementById('categoryTitles') as HTMLDivElement | null;
    const categoryItems = document.getElementById('categoryItems') as HTMLDivElement | null;

    if (categoriesRef.current && categoryTitles && categoryItems) {
      if (categoryTitles.clientHeight > categoryItems.clientHeight) {
        categoriesRef.current.style.height = `${categoryTitles.clientHeight}px`;
      } else {
        categoriesRef.current.style.height = `${categoryItems.clientHeight}px`;
      }
    }
  });
```

```css
.categories {
  transition: height 200ms ease;
}
```

![after](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/872exw8nr79zw8xfemud.gif)


voilà 🎉


## Source 
> - https://javascript.info/mutation-observer
> - https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver