Search code examples
javascriptreactjsdomreact-bootstrap

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.


Solution

  • 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