本章节将讨论一下React的生命周期
组建的生命周期可以分为三个状态:
Mounting(挂载):已经插入真实的Dom
Updating(更新):正在被重新渲染的状态
Unmounting(卸载):已经移除真实的Dom
看下面一张图,网址在这里
挂载
当组件被创建并插入在Dom中的时候,调用生命周期的顺序如下:
constructor(): 在 React 组件挂载之前,会调用它的构造函数。 child render():渲染过程中遇到Child组件 输出child render() render(): render() 方法是 class 组件中唯一必须实现的方法。 componentDidMount(): 在组件挂载后(插入 DOM 树中)立即调用。
注意:render() 方法是 class 组件中唯一必须实现的方法,其他方法可以根据自己的需要来实现。
更新
每次当组件中的state或者是props发生变化时,组件就会重新进行更新。
触发更新时,组件更新的生命周期调用顺序如下:
getDerivedStateFromProps(): 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。 shouldComponentUpdate():当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。 render(): render() 方法是 class 组件中唯一必须实现的方法。 getSnapshotBeforeUpdate(): 在最近一次渲染输出(提交到 DOM 节点)之前调用。 componentDidUpdate(): 在更新后会被立即调用。
注意: render() 方法也是 class 组件中唯一必须实现的方法,其他方法可以根据自己的需要来实现。
卸载
当组件从 DOM 中移除时会调用如下方法:
componentWillUnmount(): 在组件卸载及销毁之前直接调用。
下面是演示代码 :
index.js部分
import React, { Component } from "react"; import ReactDOM from "react-dom"; class App extends Component { // constructor钩子函数 初始化state或处理this constructor() { super(); console.log("constructor()"); this.state = { num: 0, }; // this.add = this.add.bind(this) } // render() { console.log("render()"); // 注意 不能调用setState // this.setState({ // }) return ( <> {this.state.num !== 2 ? <Child num={this.state.num} /> : <h1>hello</h1>} <button onClick={this.handleClick}>+1</button> </> ); } handleClick = () => { this.setState({ num: this.state.num + 1, }); //this.forceUpdate(); }; // 组件挂载后触发 进行dom操作或发送ajax请求 componentDidMount() { console.log("componentDidMount()"); } } class Child extends Component { render() { console.log("child render()"); return <h1 id="app">welcome to beijing {this.props.num}</h1>; } componentDidUpdate(prevProps) { console.log( "child componentDidMount()", document.getElementById("app").innerHTML ); // 不能直接用 this.setState({}); // 假如使用 setState() 配合if语句 console.log(prevProps); // 更新前props属性值 if (prevProps.num !== this.props.num) { this.setState({}); } } // 卸载阶段钩子函数-执行资源清理工作如关闭定时器。事件解绑等 componentWillUnmount() { console.log("componentWillUnmount()"); } } ReactDOM.render(<App />, document.getElementById("root"));
第一次页面显示的生命周期有
当点击按钮时出现的效果有:
再次点击更新时:
再次点击:
总结如下:
第一次渲染App组件 先执行constructor钩子函数输出constructor() 然后执行render输出render(),渲染过程中遇到Child组件 输出child render()把子组件挂载阶段的钩子函数执行完毕 执行父组件的componentDidMount()
点击按钮,父组件状态num被改变,引起父组件重新渲染render()->子组件也会更新child render()->child componentDidMount() ,{num: 0},条件成立 执行setState()->child render()->child componentDidMount() {num: 1} 条件不成立 不会执行setState