Amanda Siqueira Amanda Siqueira -4 years ago 129
React JSX Question

Get component's height every time it renders

So hey guys, basically I'm using react and I want to get the parent div's height, and make it's child to have the same height, by props. The parent div renders every time the window is resized. I tried using

componentDidMount
and
setState
to get the height of the parent, but
componentDidMount
is called only the first time my parent div renders.

And I can't use
ReactDOM.findDOMNode(this).clientHeight
inside
render()
function.

To simplify, these are the steps:


  • (Everytime) Window is resized

  • Div1 gets rendered

  • Gets Div1 height and set it state

  • Pass it by props to Div2.



Any ideas?

Here's a piece of code:

import React, { Component } from 'react';
import Div2 from './Div2';

class Div1 extends Component {
constructor(props){
super(props);
this.state = {
height: 0
};
}

componentDidMount() {
var height = (ReactDOM.findDOMNode(this).clientHeight);
this.setState({height: height})
}

render() {
return(
<div className='Div1'>
<Div2 height={this.state.height}/>
</div>
);
}
}

export default Div1;

Answer Source

There are 3 places you have to update your parent's state with new height at:

  1. componentDidMount which will be called after the first render (first time parent's div will actually appear).
  2. componentDidUpdate which is called after render-ing caused by props and state updates. You have to do only if you are actually using any props and their update can result in div's height change.
  3. window resize.

You have to use refs to get parent div's DOM element inside render method. After that you cat use it in componentDidMount and componentDidUpdate (please, check React Component Lifecycle docs).

Combining everything together results in following code, where Foo passes it's root div height to Bar:

class Bar extends React.Component {
  render() {
    return (
      <div className='bar' style={{height: `${this.props.height / 2 }px`}} />
    );
  };
};

class Foo extends React.Component {
  constructor() {
    super();
    this.state = { height: 0 };
    this.updateHeight = this.updateHeight.bind(this);
  }

 componentDidMount() {
   this.updateHeight();
   window.addEventListener("resize", this.updateHeight);
 }

 componentWillUnmount() {
   window.removeEventListener("resize", this.updateHeight);
 }

 componentDidUpdate() {
   this.updateHeight();
 }

 updateHeight() {
   if (this.state.height != this.div.clientHeight)
     this.setState({ height: this.div.clientHeight })
 }

 render() {
    return (
      <div ref={ div => { this.div = div; } } className='foo'>
        <Bar height={this.state.height} />
      </div>
    );
  }
}

ReactDOM.render(<Foo/>, document.getElementById('app'));

Working example could be found here.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download