Animating a Card Component Containing Subroutes with Resize Observer in React
Tags: react, javascript, animation, css
Published: 2024-04-03 18:40:41

In this blog post, we'll explore how to use the ResizeObserver API to animate changes in the height of a card component in a React application. This card contains subroutes, each with potentially different sizes, making it a perfect use case for the ResizeObserver.


## What is Resize Observer?
The [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) API provides a way to observe changes to an element's dimensions. It's a powerful tool for creating responsive components that need to react to changes in their size.


## Using Resize Observer in React
In our React component, we use a custom hook called [`useResizeObserver`](https://usehooks-ts.com/react-hook/use-resize-observer) from a library. This hook simplifies the process of setting up and tearing down the observer.

Here's the relevant code:

```jsx
const observedDivRef = useRef<HTMLDivElement>(null);
const targetDivRef = useRef<HTMLDivElement>(null);

useResizeObserver({
	ref: observedDivRef,
	onResize: ({ height }) => {
		if (targetDivRef.current && height) {
			targetDivRef.current.style.height = `${height + 40}px`;
		}
	}
});
```

In this code, we have two ref objects: `observedDivRef` and targetDivRef. We pass `observedDivRef` to `useResizeObserver`, which sets up a `ResizeObserver` on the element referenced by `observedDivRef`.

The onResize callback is invoked whenever the size of the observed element changes. In this callback, we check if `targetDivRef.current` is defined and if the `height` is not null. If both conditions are true, we update the height of the `targetDivRef.current` element.

This allows us to animate the height of the `targetDivRef.current` element in response to changes in the height of the `observedDivRef.current` element.

```jsx
<div 
    ref={targetDivRef}
    className="card"
    style={{
        transition: 'height 0.2s ease-out, width 0.2s ease-out', 
        background: '#FCFCFD'
    }}
>
	<div ref={observedDivRef}>
		<Routes>
			{routes.map((props) => (
				<Route key={props.path} {...props} />
			))}
		</Routes>
	</div>
</div>
```

In this code, `targetDivRef` is attached to the card `div` that we want to animate. The `div` has a style that includes a transition on the `height` and `width` properties, which will create the animation effect when the `height` or `width` changes.

The `observedDivRef` is attached to the inner `div` that contains the `Routes` component. The `height` of this `div` will change as different routes are rendered, each potentially having different sizes. The `ResizeObserver` will detect these changes and update the `height` of the `targetDivRef` `div` accordingly. This will trigger the height animation on the `targetDivRef` `div`.


## Conclusion
The `ResizeObserver` API is a powerful tool for creating responsive components in React. By observing changes to an element's dimensions, we can create animations and other dynamic behaviors that respond to changes in the size of our components. This is particularly useful for components like cards that contain subroutes with different sizes, allowing the card to smoothly adjust its size as the user navigates through the application.