Amanda Siqueira
Amanda Siqueira

Reputation: 75

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:

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;

Upvotes: 2

Views: 12606

Answers (1)

fkulikov
fkulikov

Reputation: 3199

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.

Upvotes: 5

Related Questions