React 组件生命周期

时间:2021-03-07 21:07:33

标签: javascript reactjs

据我所知,当某些事件发生时,React 从头开始​​创建一个虚拟 DOM,并将其与旧的虚拟 DOM 进行比较。如果是这种情况,那么在调用 render 方法时,react 应该创建组件并返回它们进行比较。

import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class Demo extends Component {
  constructor(props) {
    console.log("constructor called");

    super(props);
    this.state = { dummy: 1, };
  }

  render = () => <button onClick={this.props.onChange}> button </button>;
}

class App extends Component {
  state = { num: 0, };

  onChange = () => {
    this.setState({ num: this.state.num+1 }); // mutate state to trigger a render
  }

  render() {
    console.log("rendered");
    return (
      <Fragment>
        <Demo onChange={this.onChange} />
      </Fragment>
    );
  }
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

快速控制台日志显示构造函数在第一次被调用以将 Demo 组件挂载到页面上。但是,后续渲染不会创建与旧虚拟 DOM 进行比较的新 Demo 对象(因为未调用构造函数)。

起初,我的理论是,当Demo的构造函数被调用时,它会调用超级构造函数来检查是否已经存在具有相同props的类似对象。但在调用父构造函数之前移动 console.log("constructor called"); 证明了情况并非如此。

所以我的问题是 react 如何知道不创建另一个对象?

1 个答案:

答案 0 :(得分:1)

这里的关键是 Demo 没有卸载。当您第一次渲染应用程序时,它会渲染并挂载 Demo 组件并传递 onChange 道具。但是,当从 Demo 调用回调时,它会在 App 上设置状态。在 App 中调用 setState 不会卸载 Demo 组件,因此无需再次挂载。最初安装组件的时间是构造函数运行的时间。如果您在 App 组件上设置了一个开关,该开关只会在特定条件为真时在渲染中显示该组件,这将触发该组件卸载。

看看这个代码沙盒并玩一下:https://codesandbox.io/s/lifecycle-methods-vivn6?file=/src/Lifecycle.js

此外,这是一个很酷的图表,可以了解正在发生的事情:https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/ enter image description here

主要关键是构造函数在组件挂载时运行。只有在组件从 DOM 中卸载然后重新安装时,它才会再次运行。