在初始渲染时找不到引用

时间:2017-11-30 23:13:01

标签: reactjs redux react-redux

我刚刚在官方文档中读到,在第一次渲染时没有调用componentDidUpdate,我想也许这就是为什么dom没有在第一次渲染我的这个组件时定义。

这是一个弹出模式,在需要编辑页面时弹出。

还有其他方法可以解决这个问题吗?

componentDidUpdate() {
    this.renderSingularForm();
}

renderSingularForm() {
    let dom = ReactDOM.findDOMNode( this.refs.singularForm );
    if ( this.props.pageObjToEdit && dom ) {
        // DOESN'T GO HERE ON FIRST RENDER BECAUSE DOM IS NULL

        createForm( window, dom, this.props.pageObjToEdit );
    }
}

render() {
    if ( this.props.pageObjToEdit ) {
        return (
            <div>
                <div ref="singularForm" />
            </div>
        );
    }
    else {
        return null;
    }
}

2 个答案:

答案 0 :(得分:1)

您可以而且应该使用componentDidMount以安全地获取DOM元素或引用

来自DOCS:

  

componentDidMount()在组件出现后立即调用   安装。需要DOM节点的初始化应该放在这里   ...

     

然而,对于像模态和工具提示这样的情况,它可能是必要的   你需要在渲染依赖的东西之前测量DOM节点   在它的大小或位置。

另请注意您使用的是old ref API 您应该使用新的ref API

运行示例:

class App extends React.Component {
  componentDidMount() {
    console.log(this.myDiv.id);
  }

  render() {
    return (
      <div>
        <div id="some-id" ref={ref => (this.myDiv = ref)}>some div</div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

答案 1 :(得分:1)

这是关于如何使用refs的问题。你不应该再使用字符串引用,因为它们will be deprecated soon。大多数人现在使用内联引用(ref={ref => this.input = ref}),但是当您这样做时,组件第一次呈现它将获得null值。然后在第二个渲染上,将使用DOM元素正确分配引用。

为了解决这个问题,你应该为ref道具而不是内联函数提供一个类方法。

示例:

此:

render() {
    return (
        ...
        <div ref="singularForm" />
        ...
    )
}

应该是:

applyRef = ref => {
    this.singularForm = ref;
}
render() {
    return (
        ...
        <div ref={this.applyRef} />
        ...
    )
}

使用类方法应用ref时,只有在将实际元素添加到dom时才会调用一次,因此您不应再获取初始null值。

更新10月18日:

您现在可以使用新的React.createRef完全避免此问题来创建您的参考。