Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Get: Component Width After Render in React

I'm trying to create a general purpose component, that I can reuse in other applications. I need to know the width of the component after render so that I can modify the content of the component.

I've been trying to use the different life cycles in react without success.

componentDidUpdate() {
  console.log('width', this.element.offsetWidth);
}

render() {
  return (
    <div ref={(element) => {this.element = element }} />
  );
}

When I try this I get the width of the screen, but if I change the size of the window, I get the width of the component. See the Chrome Log:

Chrome log

ComponentDidMount executes before render so this.element is undefined.

I've also attempted to use different libraries from npm to solve this without luck.

Futher information: The component has to work inside a Bootstrap column, at different widths.

render() {
  <Row>
    <Col sm={3} />
      <MyComponent />
    </Col>
    <Col sm={9} />
      <MyComponent />
    </Col>
  <Row>
}

Clarification I do not want to resize the window, and I apologize for not being clear. The only reason for me to mention the resizing is that when the DOM has been created and I resize, I get the correct value in offsetWidth. I'm looking for a solution where I get the correct value without resizing. Either a post render function call, listeners, some react magic, or other solutions. My problem is my lack of knowledge with the virtual vs. real DOM.

like image 662
R. Gulbrandsen Avatar asked Sep 01 '17 08:09

R. Gulbrandsen


People also ask

How do you find the width of a component?

To get the width of an element in a React component, we can assign a ref to the element we want to get the width of. Then we can use the offsetWidth property to get the width. to add the ref with the useRef hook. Then we pass ref as the value of the ref prop to assign the ref to the div.

How do you find the parent width in React?

To get the parent height and width in React: Set the ref prop on the element. In the useEffect hook, update the state variables for the height and width. Use the offsetHeight and offsetWidth properties to get the height and width of the element.


2 Answers

I was unable to solve this problem with the answers given here. I only got the width of the browser window and not the component within. After some research, it looks like I'm having a chicken or the egg problem with the render. After some more research, I found react-sizeme that solves the issue.

import React, { Component } from 'react';
import sizeMe from 'react-sizeme';

class MyComponent extends Component {
  render() {
    const { width } = this.props.size;

    return (
      <div style={{
        width: '100%',
        backgroundColor: '#eee',
        textAlign: 'center'
      }}>
        <span>My width is: {Math.floor(width)}px</span>
      </div>
    );
  }
}

export default sizeMe()(MyComponent);

Which will produce the following when it first renders

enter image description here

like image 107
R. Gulbrandsen Avatar answered Nov 14 '22 21:11

R. Gulbrandsen


If you need to hold component width state you can do something like this:

componentDidMount(){ 

          this.boundingBox = this.element.getBoundingClientRect();

          this.setState({ 
              width:this.boundingBox.width
          }); 

          Observable.fromEvent(this.element,"resize")
          .subscribe(
              () => { 
                this.boundingBox = this.element.getBoundingClientRect();  
                this.setState({ 
                    width:this.boundingBox.width
                }); 
              }
          );

};    

You can replace Observable with event listener. Alternatively you can update bounding box attached to class and derive state from it somewhere else.

componentDidUpdate(){ 
          this.boundingBox = this.element.getBoundingClientRect();
};     
like image 22
Anatoly Strashkevich Avatar answered Nov 14 '22 21:11

Anatoly Strashkevich