question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

componentDidMount is called before the visual is rendered

See original GitHub issue

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);
  }

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:1
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
jimfbcommented, Feb 4, 2016

Hmm. I get 300 both times, even when I check a full second later (http://jsfiddle.net/r94vwoxr/).

Honestly, I’m not an SVG expert, but this looks like a usage question. React is responsible for creating the DOM/SVG nodes before calling componentDidMount, but everything I’m seeing here seems to indicate React has done that correctly. Beyond that, it’s up to the browser.

To me, this looks like a usage question, rather than a bug in the React core. Usage questions are better answered on sites like StackOverflow, as we try to use github issues for tracking bugs in the React core, and I don’t see anything here to indicate that React isn’t doing it’s job. I suspect some kind of race condition, where the SVG nodes are created but the browser is still doing SVG layout or something. Perhaps there is a command to force SVG to flush, or perhaps it’s a bug in chrome, or something. If you are able to come up with a clear example/jsfiddle that demonstrates a bug in the React core, let me know and we can re-investigate. Otherwise, I’d recommend asking on StackOverflow.

2reactions
jimfbcommented, Feb 4, 2016

Hmm…

¯_(ツ)_/¯

Try: console.log('component did mount. The ribbon\'s width is', this.refs.ribbonSvg.offsetWidth);

Read more comments on GitHub >

github_iconTop Results From Across the Web

React render() is being called before componentDidMount()
When a component is mounted it is being inserted into the DOM. This is when a constructor is called. componentWillMount is pretty much ......
Read more >
React Lifecycle Methods Render And ComponentDidMount
As the name suggests, after all the elements of the page is rendered correctly, this method is called. After the markup is set...
Read more >
React.Component
shouldComponentUpdate() is invoked before rendering when new props or state are being received. Defaults to true . This method is not called for...
Read more >
React lifecycle methods: An approachable tutorial with examples
After render is called, the component is mounted to the DOM and the componentDidMount method is invoked. This function is invoked immediately ...
Read more >
Why is it recommended to do Ajax in componentDidMount ...
It sounds a bit counter intuitive to fully render the component before you even start to fetch data. There is a lifecycle method...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found