在真正的DOM可用之前调用componentDidMount

时间:2017-03-28 18:49:51

标签: javascript reactjs dom render getelementbyid

我对React很新。我需要得到一个元素的高度,所以我试图在componentDidMount方法得到它。我知道在渲染组件之后调用了这个方法,最后编写了我假设的真实DOM。但是,在最终DOM可用之前,正在调用componentDidMount。怎么样?

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

2 个答案:

答案 0 :(得分:2)

在React上,你不应该依赖render方法返回的DOM。组件和渲染部分是React中的2个不同进程,因此从外部进入的方法在React中不起作用。你可以做的是,将评论保存为参考:

 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:在类似的情况下,我使用了这个神奇的库:https://github.com/wnr/element-resize-detector

答案 1 :(得分:0)

你的选择器const el = window.document.getElementById('comments');(这是反模式) 为空,因为您的选择节点不存在于componentDidiMount渲染生命周期中。

您需要选择节点的内部React模式(或shadow DOM)。

更改此代码块的代码,替换javascript选择器&#39; getElementBy&#39;对于React的参考。查看文档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>
  );
}