簡體   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