componentDidMount is called before the visual is rendered
See original GitHub issueI 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:
- Created 8 years ago
- Reactions:1
- Comments:5 (3 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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.
Hmm…
¯_(ツ)_/¯
Try:
console.log('component did mount. The ribbon\'s width is', this.refs.ribbonSvg.offsetWidth);