繁体   English   中英

在子支架上访问父组件的子组件中的Ref

[英]Access parent's Ref in child component on child mount

我具有以下父/子组件。 最初渲染Child组件后,我需要滚动到顶部。

import React, {Component} from 'react';
import Child from "./Child";

class Parent extends Component {

  render() {
    return (
      <div>
        <div ref={topDiv => {
          this.topDiv = topDiv;
        }}/>
        <Child
          topDiv={this.topDiv}
        />
      </div>
    );
  }
}

export default Parent;
import React, {Component} from 'react';

class Child extends Component {

  componentDidMount() {
    this.scrollToTop();
  }

  // componentWillReceiveProps(nextProps, nextContext) {
  //   nextProps.topDiv.scrollIntoView();
  // }

  scrollToTop() {
    this.props.topDiv.scrollIntoView();
  }

  render() {
    return (
      <div style={{height: '500rem'}}>
        Long Child
      </div>
    );
  }
}

export default Child;

使用此,我得到错误:

TypeError:无法读取未定义的属性“ scrollIntoView”

我认为这是因为调用componentDidMount时,尚未收到道具,因此topDiv为null / undefined。

如果我使用注释部分所示的componentWillReceiveProps ,则可以正常工作。 但我不能使用它,因为:
1.不推荐使用。
2.我认为每次收到道具时都会调用它。 因此,我想我需要保留一个变量以了解是否是第一次收到道具?

我不能使用componentDidUpdate因为文档 显示初始渲染未调用此方法。 ”。

渲染组件后首次收到道具时该怎么办?

道具绝对应该在componentDidMount可用。

看来这可能是由于React生命周期中有些混乱。

在父级中,大约在安装Child的同时,在渲染器中提供ref回调。 根据React docs

当组件安装时,React将使用DOM元素调用ref回调,而在卸载时使用null调用它。 保证在componentDidMount或componentDidUpdate触发之前,引用是最新的。

但是,子级的componentDidMount将在其父级的componentDidMount之前触发,因此,此保证并不意味着Parentthis.topDiv将在Child调用componentDidMount之前定义。 (而且,进一步考虑,它绝对不能保证在将其作为道具提供给Child之前将其定义。)

在您父母的身边,您可以尝试类似

componentDidMount() {
    this.setState({ divSet: true });
}

render() {
    let child = null;
    if (this.state.divSet) {
        child = <Child topDiv={this.topDiv} />
    }

    return (
      <div>
        <div ref={topDiv => {
          this.topDiv = topDiv;
        }}/>
        {child}
      </div>
    );
  }

这将确保您的ref在Child挂载之前被设置。 setState专门用于在设置ref时强制父级重新呈现。

根据定义,您正在尝试做的事情是不可能的! 当你说

最初渲染Child组件后,我需要滚动到顶部。

你的意思是父母的右上角?

但是这里的关键细节是

您的孩子完成渲染后,您的父母还没有渲染! 没有顶部可以滚动到!


组件的生命周期

这是组件的典型生命周期流程

  1. 构造函数()
  2. componentWillMount()
  3. 渲染()
  4. componentDidMount()

当涉及到亲子关系时

  1. [父]构造()
  2. [父] componentWillMount()
  3. [父]渲染()
    1. [儿童]构造()
    2. [儿童] componentWillMount()
    3. [儿童]渲染()
    4. [Child] componentDidMount()-父级不存在
  4. [父] componentDidMount()

也是关于新添加的生命周期方法的一则小注释,它代替了componenWillRecieveProps

getDerivedStateFromProps(道具,状态)

在初始安装和后续更新上,都在调用render方法之前立即调用getDerivedStateFromProps。 它应该返回一个对象以更新状态,或者返回null则不更新任何内容。


因此,最好的选择是在您的组件componentDidMount中调用滚动顶部,您可以在其中访问其引用。

如果仍然确定要在子组件中执行此操作,则必须结合使用getDerivedStateFromProps和状态标记来检测是否已至少滚动到顶部一次。 总体上来说这可能有点高效和肮脏。

在此处查看组件生命周期的凉爽流程图,以了解其清晰性!

this.scrollToTop绑定到constructor类组件:

class Child extends Component {
  constructor() {
    this.scrollToTop = this.scrollToTop.bind(this);
  }
  ...rest of your component code

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM