Javascript 反应组件生命周期

Javascript 反应组件生命周期,javascript,reactjs,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

据我所知,当某些事件发生时,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')
);
import React,{Component,Fragment}来自'React';
从“react dom”导入react dom;
导入“./index.css”;
类Demo扩展了组件{
建造师(道具){
log(“调用的构造函数”);
超级(道具);
this.state={dummy:1,};
}
渲染=()=>按钮;
}
类应用程序扩展组件{
状态={num:0,};
onChange=()=>{
this.setState({num:this.state.num+1});//修改状态以触发渲染
}
render(){
控制台日志(“呈现”);
返回(
);
}
}
ReactDOM.render(
,
document.getElementById('root'))
);
一个快速的控制台日志显示第一次调用构造函数将
Demo
组件装载到页面上。但是,后续渲染不会创建与旧虚拟DOM比较的新
Demo
对象(因为未调用构造函数)

首先,我的理论是,当调用
Demo
的构造函数时,它会调用超级构造函数来检查是否已经存在具有相同道具的类似对象。但移动
console.log(“构造函数调用”)证明了情况并非如此


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

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

看看这个代码沙盒,玩一玩:

此外,这是一个很酷的图表,可以了解正在发生的事情:


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

它不会创建新的虚拟树,它只是递归地调用“render”方法并比较结果差异,以查看与以前的渲染相比发生了什么变化,以及需要更新到实际DOM的内容。好的,谢谢。但是react如何知道我没有尝试使用
挂载新组件?毕竟,我没有提供一个
,因此两个对象都将具有
key=null
。它已经第一次将该组件呈现到DOM中,并且没有将其从DOM中删除。再次调用render时,它将生成相同的标记。在对集合进行迭代时,特别是对元素进行排序时,key属性非常重要。基本上,安装是第一次渲染。渲染组件后,react将存储对该组件的引用,并在再次调用render时对其进行更新。这篇文章应该有助于: