Modern browsers now have native support for detecting element size changes through ResizeObservers. This library utilizes ResizeObservers to facilitate managing element size changes in React applications.
🐥 Tiny ~2kb
🐼 Written in TypeScript
🐠 Used by 170k repositories
🦄 Produces 100 million downloads annually
No window.resize
listeners! No timeouts!
Container queries now work in all major browsers. It's very likely you can solve your task using pure CSS.
Example
<div class="post">
<div class="card">
<h2>Card title</h2>
<p>Card content</p>
</div>
</div>
.post {
container-type: inline-size;
}
/* Default heading styles for the card title */
.card h2 {
font-size: 1em;
}
/* If the container is larger than 700px */
@container (min-width: 700px) {
.card h2 {
font-size: 2em;
}
}
npm i react-resize-detector
// OR
yarn add react-resize-detector
import { useResizeDetector } from 'react-resize-detector';
const CustomComponent = () => {
const { width, height, ref } = useResizeDetector();
return <div ref={ref}>{`${width}x${height}`}</div>;
};
import { useResizeDetector } from 'react-resize-detector';
const CustomComponent = () => {
const onResize = useCallback(() => {
// on resize logic
}, []);
const { width, height, ref } = useResizeDetector({
handleHeight: false,
refreshMode: 'debounce',
refreshRate: 1000,
onResize
});
return <div ref={ref}>{`${width}x${height}`}</div>;
};
It's not advised to use this approach, as dynamically mounting and unmounting the observed element could lead to unexpected behavior.
import { useResizeDetector } from 'react-resize-detector';
const CustomComponent = () => {
const targetRef = useRef();
const { width, height } = useResizeDetector({ targetRef });
return <div ref={targetRef}>{`${width}x${height}`}</div>;
};
Prop | Type | Description | Default |
---|---|---|---|
onResize | Func | Function that will be invoked with width , height and ResizeObserver entry arguments |
undefined |
handleWidth | Bool | Trigger onResize on width change |
true |
handleHeight | Bool | Trigger onResize on height change |
true |
skipOnMount | Bool | Do not trigger onResize when a component mounts | false |
refreshMode | String | Possible values: throttle and debounce See lodash docs for more information. undefined - callback will be fired for every frame |
undefined |
refreshRate | Number | Use this in conjunction with refreshMode . Important! It's a numeric prop so set it accordingly, e.g. refreshRate={500} |
1000 |
refreshOptions | Object | Use this in conjunction with refreshMode . An object in shape of { leading: bool, trailing: bool } . Please refer to lodash's docs for more info |
undefined |
observerOptions | Object | These options will be used as a second parameter of resizeObserver.observe method. |
undefined |
targetRef | Ref | Use this prop to pass a reference to the element you want to attach resize handlers to. It must be an instance of React.useRef or React.createRef functions |
undefined |
Thanks to @Primajin for posting this snippet
const { ResizeObserver } = window;
beforeEach(() => {
delete window.ResizeObserver;
window.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn()
}));
wrapper = mount(<MyComponent />);
});
afterEach(() => {
window.ResizeObserver = ResizeObserver;
jest.restoreAllMocks();
});
it('should do my test', () => {
// [...]
});
MIT
Show us some love and STAR ⭐ the project if you find it useful