Reputation: 5958
I'm very new to React. I need to get the height of an element, so I'm trying to get it at componentDidMount
method. I understood that this method was called after rendering the component, which is at the end to write the real DOM I assume. However, componentDidMount
is being called before the final DOM is available. How come?
componentDidMount() {
const el = window.document.getElementById('comments'); // el is null
console.log(el);
}
resize() {
const el = window.document.getElementById('comments'); // el is null
console.log(el);
}
render() {
const { name } = this.props;
const Comments = this.props.comments.filter(comment => comment.body !== null && comment.body !== '').map(comment => <Comment key={comment.id} comment={comment} />);
return (
<div ref={this.resize}>
<div>
<div id="comments">
{ Comments }
</div>
</div>
</div>
);
}
Upvotes: 1
Views: 2567
Reputation: 10967
On React you shouldn't rely on DOM that is returned by render method. The component and the render part are 2 different processes in React so the approach from outside in doesn't work in React. What you can do is, save comments as a ref :
componentDidMount() {
var erd = elementResizeDetectorMaker();
erd.listenTo(this.refs.comments, resize);
}
resize(element) {
//do-some-thing
}
render() {
const { name } = this.props;
const Comments = this.props.comments.filter(comment => comment.body !== null && comment.body !== '').map(comment => <Comment key={comment.id} comment={comment} />);
return (
<div>
<div>
<div ref={comments => { this.comments = comments; }}>
{ Comments }
</div>
</div>
</div>
);
}
PS : In a similar situation I used this amazing library : https://github.com/wnr/element-resize-detector
Upvotes: 2
Reputation: 800
Your selector const el = window.document.getElementById('comments');
(this is anti pattern)
is null because your select Node don't exist on componentDidiMount
render lifecycle.
You need select your node's inner React pattern (or shadow DOM).
Change your code for this code block, replace javascript selector 'getElementBy' for refs of React. Check documentation https://facebook.github.io/react/docs/refs-and-the-dom.html
componentDidMount() {
let el = this.refs['comments']
console.log(el.clientHeight)
this.resize()
}
resize() {
let el = this.refs['comments']
console.log(el.clientHeight)
}
render() {
const { name } = this.props;
const Comments = this.props.comments.filter(comment => comment.body !== null && comment.body !== '').map(comment => <Comment key={comment.id} comment={comment} />);
return (
<div ref='comments'>
<div>
<div id="comments">
{ Comments }
</div>
</div>
</div>
);
}
Upvotes: 0