当前位置: 首页 > 面试题库 >

componentDidMount在引用回调之前被调用

夹谷志
2023-03-14
问题内容

问题

我正在ref使用内联函数定义设置反应

render = () => {
    return (
        <div className="drawer" ref={drawer => this.drawerRef = drawer}>

然后在componentDidMountDOM引用中未设置

componentDidMount = () => {
    // this.drawerRef is not defined

我的理解是,ref回调应该在安装期间运行,但是在ref回调函数 之前*
调用添加console.log语句揭示。componentDidMount
*

例如,我看过的其他代码示例在github上的讨论都表明相同的假设,componentDidMount应该在中定义的任何回调
之后ref调用render,甚至在对话中也要说明

那么在所有的ref回调都执行完之后,componentDidMount是否被触发?

是。

我正在使用反应 15.4.1

我尝试过的其他事情

为了验证该ref函数是否已被调用,我尝试在此类上定义

setDrawerRef = (drawer) => {
  this.drawerRef = drawer;
}

然后在 render

<div className="drawer" ref={this.setDrawerRef}>

在这种情况下,控制台日志记录显示确实在 之后* 调用了回调 *componentDidMount


问题答案:

简短答案:

React保证引用被设置在componentDidMountcomponentDidUpdate钩子之前。但仅适用于 实际上被渲染
过的孩子

componentDidMount() {
  // can use any refs here
}

componentDidUpdate() {
  // can use any refs here
}

render() {
  // as long as those refs were rendered!
  return <div ref={/* ... */} />;
}

请注意,这并不意味着“ React总是在运行这些挂钩之前设置 所有 引用”。
让我们看一些 没有 设置参考的示例。

React只会为您实际 从render返回的 元素调用ref回调。

这意味着如果您的代码看起来像

render() {
  if (this.state.isLoading) {
    return <h1>Loading</h1>;
  }

  return <div ref={this._setRef} />;
}

并初步this.state.isLoadingtrue,你应该
希望this._setRef之前调用componentDidMount

这应该是有道理的:如果您的第一个渲染器返回了<h1>Loading</h1>,React无法知道在其他条件下它会返回需要附加引用的其他内容。也
没有将ref设置为的内容:<div>元素未创建,因为render()方法表示不应渲染该元素。

因此,在此示例中,只会componentDidMount触发。但是,对
进行this.state.loading更改时false,您将this._setRef首先看到附件,然后componentDidUpdate将其触发。

提防其他组件

请注意, 如果您将带有ref的子级传递给其他组件 ,则它们可能会执行某些阻止渲染的操作(并导致问题)。

例如,这:

<MyPanel>
  <div ref={this.setRef} />
</MyPanel>

如果其输出中MyPanel未包含以下内容props.children,则将不起作用:

function MyPanel(props) {
  // ignore props.children
  return <h1>Oops, no refs for you today!</h1>;
}

再说一次,这不是一个错误: React没有任何设置引用的原因,因为DOM元素没有创建

如果将引用传递给嵌套,则它们不会在生命周期之前设置 ReactDOM.render()

与上一节类似,如果将带有ref的孩子传递到另一个组件,则此组件可能会执行某些阻止及时附加ref的操作。

例如,也许不是从中返回子项render(),而是调用ReactDOM.render()了生命周期挂钩。您可以在这里找到一个示例。在该示例中,我们呈现:

<MyModal>
  <div ref={this.setRef} />
</MyModal>

但是在 生命周期方法中MyModal执行ReactDOM.render()调用: __componentDidUpdate

componentDidUpdate() {
  ReactDOM.render(this.props.children, this.targetEl);
}

render() {
  return null;
}

从React 16开始, 生命周期内的 此类 顶级渲染调用将被延迟,直到整个树的生命周期都已运行为止 。这可以解释为什么您没有及时看到引用。

解决此问题的方法是使用
门户网站而不是嵌套ReactDOM.render调用:

render() {
  return ReactDOM.createPortal(this.props.children, this.targetEl);
}

这样<div>,带有ref的我们实际上包含在渲染输出中。

因此,如果遇到此问题,则需要验证组件和ref之间没有任何东西可能会延迟渲染子级。

不要setState用来存储裁判

确保您setState不习惯将ref存储在ref回调中,因为它是异步的,并且在“完成”之前componentDidMount将首先执行。

还是一个问题?

如果以上提示均无济于事,请在React中提出问题,我们将进行调查。



 类似资料:
  • 我正在尝试在像这样: 然后在我的它呈现: 我正在将我的fetch记录到控制台中,它被调用了三次。流程是我在登录页面上(加载时挂载一次),我登录,它将我重定向到自己呈现的主页。此时,我在控制台中看到:

  • 我是ReactJS的新手,我现在对组件生命周期方法的工作方式感到困惑;在我的例子中,这与ReactJS. org文档完全矛盾。预期的行为是在渲染()之前执行,但是渲染()在组件迪蒙()之前执行。 我的源代码: 类变量this.cache是如果被调用在,但它占用的值如果在中调用。

  • 问题内容: 我父母的渲染中有以下代码 以及下面我孩子图表中的代码 我以为仅在所有子项都加载后才调用父级的componentDidMount。但是在这里,父级的componentDidMount在子级的componentDidMount之前被调用。 这是工作方式吗?还是我做错了什么。 如果这是工作方式,我如何检测从父级加载所有子级组件的时间? 问题答案: 是的,孩子的称为父母之前的。 运行下面的代码

  • 在我正在工作的一个项目中,我使用了paginglibrary和Reverfit。这是我第一次这么做。 数据正常返回。但是我注意到我的viewmodel(更确切地说是我的LiveData)中的观察者在我的PageKeyedDataSource中的LoadIsitial回调之前被调用。这将使传递给适配器的列表为空。为什么在我回调之前调用Observer?

  • 问题内容: 我有一个jQuery对话框打开,然后进行AJAX调用。我想这样做,以便如果关闭对话框或按下“取消”按钮,则取消AJAX调用,并且不调用其回调函数。我可以想到一些使用变量的方式,例如: 但是,从某种程度上来说,这对我来说很肮脏,并且实际上并没有阻止AJAX调用完成。是否有内置的方式来取消正在进行的AJAX呼叫? 问题答案: 好的,因此基于使用$ .get函数返回的XmlHttpReque

  • 问题内容: 如果没有线程正在等待,使用,任何来电或没有任何效果。我有一种情况,如果在等待集为空时调用,则后续调用不应将线程置于等待状态。如何做到这一点?信号量可能是我能想到的一种解决方案。有没有更优雅的解决方案? 问题答案: 这种情况似乎非常适合。呼叫而不是和而不是等待。