Skip to content

componentDidMount is called before the visual is rendered #5979

@lcoderre

Description

@lcoderre

I am trying to get visual attributes (width to be precise) of a component once it's rendered and CSS is applied. I've been trying with componentDidMount but width is still 0, I am not sure what I'm doing wrong.

output:

rendering
component did mount. The ribbon's width is 0

And after that, if I click on my header's button to "re-route" back to the same page (i.e. trigger an update), then the componentDidUpdate is called with the proper width. Am I missing something or is this a bug?

Thanks you lots folks.

import React, {Component} from 'react';

export default class RibbonHeader extends Component {
  componentDidMount() {
    console.log('component did mount. The ribbon\'s width is', this.refs.ribbonSvg.width.animVal.value); // is 0
    this.paintInSVG();
  }

  shouldComponentUpdate() {
    console.log('should component update'); // never called
    return true;
  }

  componentDidUpdate() {
    // Not automatically called, but if I generate a routing event, it updates
    console.log('component did update. The ribbon\'s width is', this.refs.ribbonSvg.width.animVal.value);  // width is 1020px (good)
    this.paintInSVG();
  }

  paintInSVG() {
    const refRibbon = this.refs.ribbonSvg;
    doSomeSVGMagicThatDependsOnTheWidth(refRibbon);
  }

  render() {
    console.log('rendering');

    return (
      <svg ref="ribbonSvg" styles={{width: '100%'}}></svg>
    );
  }
}

EDIT:
Adding a timeout to componentDidMount does the job, although this is probably not normal

  componentDidMount() {
    setTimeout(() => {
      this.paintInSVG();
    }, 100);
  }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions