reactjs - react : Function call after render() and before child's constructor()

标签 reactjs react-component react-lifecycle

我有一个名为 Parent 的组件,其中有另一个名为 Child 的组件:

<Parent>
  <Child/>
</Parent>

所以生命周期如下:

  1. 父构造函数
  2. 父级的 render()
  3. 子构造器
  4. child 的 render()
  5. child 骑上了
  6. 父级已挂载

我可以在第 2 步之后和第 3 步之前以某种方式进行额外的父级初始化吗?

更新:

class ThirdPartyLib {
  init(elementId) {
    console.log(`initializing element: ${elementId}`);
    // element with #id: elementId should exist!
    // document.getElementById(elementId).style.color = "red";
  }
}

class Parent extends React.Component {
    constructor(props) {
        super(props);
        console.log("Parent's constructor");
    }

    render() {
        console.log("rendering Parent");
        new ThirdPartyLib().init("parent");
        return (
            <div id="parent">Parent: {this.props.name}
                <Child name="Sara"/>
            </div>
        );
    }

    componentDidMount() {
        console.log("Parent is mounted");
    }
}

class Child extends React.Component {
    constructor(props) {
        super(props);
        console.log(`Child ${this.props.name} constructor`);
    }

    render() {
        console.log(`rendering Child: ${this.props.name}`);
        return <div>Child: {this.props.name}</div>
    }

    componentDidMount() {
        console.log(`Child ${this.props.name} is mounted`);
    }
}

ReactDOM.render(<Parent name="Bob"/>, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="app"></div>

这里我做了一些简化 - 我不仅仅是改变元素的颜色,我可以在 componentDidMount() 方法中进行。相反,ThirdPartyLib 细节决定了初始化顺序。在创建任何子元素之前,我必须在它出现在 DOM 中后立即初始化 Parent。

更具体地说,ParentChild 共享 ThirdPartyLib 类的完全相同的实例。我不能将初始化逻辑放入 Parent 的 render() 函数中,因为该元素还不在 DOM 中。同样,我无法按照通过 componentDidMount() 的评论中的建议在 Child 之前初始化 Parent,因为 ChildcomponentDidMount()Parent 之前执行。

最佳答案

解决此问题的一种方法是延迟渲染子项,直到父项挂载之后。这些步骤如下所示:

  • 初始父级渲染不渲染子级(例如,在父级状态下使用标志抑制)
  • 父级 componentDidMount 执行第三方初始化并更改父级状态中的标志,触发父级的重新渲染
  • Parent 的重新渲染现在将渲染 Child,并且 Parent 可以通过 prop 将第三方初始化信息传递给 Child

生成的代码类似于:

import React from "react";
import ReactDOM from "react-dom";

class ThirdPartyLib {
  init(elementId) {
    console.log(`initializing element: ${elementId}`);
    this.element = document.getElementById(elementId);
    this.element.style.color = "red";
  }
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { initialized: false };
    console.log("Parent's constructor");
  }

  render() {
    console.log("rendering Parent");
    return (
      <div id="parent">
        Parent: {this.props.name}
        {this.state.initialized && (
          <Child name="Sara" thirdPartyLib={this.state.thirdPartyLib} />
        )}
      </div>
    );
  }

  componentDidMount() {
    console.log("Parent is mounted");
    const thirdPartyLib = new ThirdPartyLib();
    thirdPartyLib.init("parent");
    this.setState({ initialized: true, thirdPartyLib });
  }
}

class Child extends React.Component {
  constructor(props) {
    super(props);
    console.log(`Child ${this.props.name} constructor`);
    console.log(
      `Child knows stuff from thirdPartyLib: ${
        this.props.thirdPartyLib.element.id
      }`
    );
  }

  render() {
    console.log(`rendering Child: ${this.props.name}`);
    return (
      <div>
        Child: {this.props.name}
        <br />
        ThirdPartyLib element id:
        {this.props.thirdPartyLib.element.id}
      </div>
    );
  }

  componentDidMount() {
    console.log(`Child ${this.props.name} is mounted`);
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Parent name="Bob" />, rootElement);

Edit 82q69v3469

关于reactjs - react : Function call after render() and before child's constructor(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54219364/

相关文章:

reactjs - React Native 中如何销毁组件实例以避免内存泄漏并释放 native 代码的底层 View 对象?

javascript - 警告 : setState(. ..) : Can only update a mounted or mounting component. 这通常意味着

reactjs - 卸载后取消 Redux 操作

css - 为什么当我点击这个 Material-UI Grid item 时它会移动?

javascript - React 功能组件中的 Prop 名称

javascript - react : can't access passed props (but CAN access props from router)

javascript - onChange 没有在 react js 中触发

javascript - componentDidMount 生命周期方法中的条件异步操作不断循环

reactjs - 单元测试 Apollo,在 mutation mock 上出错

reactjs - React js 中 getDerivedStateFromProps 中的多个 props 验证