Using ResizeObserver in React class component
Solution 1
EDIT: Davidicus's answer below is more complete, look there first
ResizeObserver can't go in the constructor because the div doesn't exist at that point in the component lifecycle.
I don't think you can get around the extra div because react components reduce to html elements anyway.
Put this in componentDidMount and it should work:
componentDidMount() {
const resizeObserver = new ResizeObserver((entries) => {
console.log("Hello World");
});
resizeObserver.observe(document.getElementById("myDivTag"));
}
Solution 2
ComponentDidMount
would be the best place to set up your observer but you also want to disconnect on ComponentWillUnmount
.
class MyComponent extends React.Component {
resizeObserver = null;
resizeElement = createRef();
componentDidMount() {
this.resizeObserver = new ResizeObserver((entries) => {
// do things
});
this.resizeObserver.observe(this.resizeElement.current);
}
componentWillUnmount() {
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
}
render() {
return (
<div ref={this.resizeElement}>
...
</div>
);
}
}
Solution 3
I was fighting a the similar problem recently with the difference that my app is predominantly using hooks and functional components.
Here is an example how to use the ResizeObserver within a React functional component (in typescript):
const resizeObserver = React.useRef<ResizeObserver>(new ResizeObserver((entries:ResizeObserverEntry[]) => {
// your code to handle the size change
}));
const resizedContainerRef = React.useCallback((container: HTMLDivElement) => {
if (container !== null) {
resizeObserver.current.observe(container);
}
// When element is unmounted, ref callback is called with a null argument
// => best time to cleanup the observer
else {
if (resizeObserver.current)
resizeObserver.current.disconnect();
}
}, [resizeObserver.current]);
return <div ref={resizedContainerRef}>
// Your component content here
</div>;
noblerare
Updated on June 16, 2022Comments
-
noblerare almost 2 years
I am using React 15 on Chrome and want to hook up an event listener to detect changes to a parent container. After looking around for options, I came across ResizeObserver and am not sure how to get it to work in my project.
Currently, I am putting it in my constructor but it does not seem to print any text and I am not sure what to put in the
observe
call.class MyComponent extends React.Component { constructor(props) { super(props); const resizeObserver = new ResizeObserver((entries) => { console.log("Hello World"); }); resizeObserver.observe(somethingGoesHere); } render() { return ( <AnotherComponent> <YetAnotherComponent> </YetAnotherComponent> <CanYouBelieveIt> </CanYouBelieveIt> <RealComponent /> </AnotherComponent> ); } }
Ideally, I also don't want to wrap
RealComponent
in adiv
and give thatdiv
an id. Is there a way to theRealComponent
directly?My goal is to observe any resize changes to the
RealComponent
butMyComponent
is fine too. What should I put in thesomethingGoesHere
slot?EDIT:
For the sake of getting something to work, I bit the bullet and wrapped a
div
tag aroundRealComponent
. I then gave it an id<div id="myDivTag">
and changed theobserve
call:resizeObserver.observe(document.getElementById("myDivTag"));
However, when running this, I get:
Uncaught TypeError: resizeObserver.observe is not a function
Any help would be greatly appreciated.
-
Johns3n over 4 yearsIs it good react practice to create instances inside a component like that?
-
Christophe about 2 yearsWhat TS target are you using? I am getting an error with target:es6.
-
Vočko about 2 years@Christophe I think 2015. ResizeObserver is not supported in any version of IE, you might need to use some polyfill like github.com/que-etc/resize-observer-polyfill. I luckily don't have to worry about ie. support anymore.