I found some relevant questions with this but none of them can't solve my problem. So, I wrote this post. If there are any relevant threads, please let me know.
I am trying to get the size (in px unit) of div element so that I can draw some SVG groups inside of it. For that, I wrote following React class after searching the web for a while.
class ChartBox extends React.Component {
constructor() {
super();
this.state = {width: 0, height: 0}
}
componentDidMount() {
window.addEventListener('resize', () => this.handleResize());
this.handleResize();
}
componentWillUnmount() {
window.removeEventListener('resize', () => this.handleResize());
}
handleResize = () => {
this.setState({
width: this.container.offsetWidth,
height: this.container.offsetHeight
});
}
render() {
return (
<div className={this.props.className}>
<div className={theme.up}>
<div className={theme.left}>up.left</div>
<div className={theme.right}
ref={c => this.container = c}>
<p>up.right</p>
<p>`${this.state.width}x${this.state.height}`</p>
</div>
</div>
<div className={theme.down}>
<div className={theme.left}> down.left </div>
<div className={theme.right}>down.right</div>
</div>
</div>
);
}
}
The ChartBox class get a style of the outer-most div element from a parent React element. And for all inner div elements in the ChartBox class, I import following css.
:root {
--right-width: 100px;
--top-height: 100px;
--left-width: calc(100% - var(--right-width));
--bottom-height: calc(100% - var(--top-height));
}
.up {
float: left;
width: 100%;
height: var(--top-height);
padding: 0px
}
.bottom {
float: left;
width: 100%;
height: var(--bottom-height);
padding: 0px
}
.left {
float: left;
width: var(--left-width);
height: 100%;
padding: 0px
}
.right {
float: left;
width: var(--right-width);
height: 100%;
padding: 0px
}
As you can imagine, I am trying to divide the outer-most div element into four sections where the smallest div element has a size of 100px by 100px.
First of all, all elements are mounted correctly when I checked it visually. However, the returned values are incorrect. For example, when I first reload the page, it returns 762 x 18 that is incorrect. But after resizing the window, it returns correct size as 100 x 100.
Any suggestions or comments to solve this issue?
I had a similar issue. I had to use setTimeout(0) for this. For example:
handleResize = () => {
setTimeout(() => {
this.setState({
width: this.container.offsetWidth,
height: this.container.offsetHeight
});
}, 0 );
}
This ensures that the function call happens at the end of the call stack and after the container has fully rendered.
Update:
I actually found a better solution using getSnapshotBeforeUpdate. No set timeout is needed with this. From the React docs: "It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed."
For example:
getSnapshotBeforeUpdate() {
let width = this.container.offsetWidth;
let height = this.container.offsetHeight;
return { width, height };
}
componentDidUpdate( prevProps, prevState, snapshot ) {
if (prevState.width !== snapshot.width || prevState.height !==
snapshot.height) {
this.setState({
height: snapshot.height,
width: snapshot.width,
})
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With