Skip to main content

React class的生命周期

类组件的state生命周期图

挂载#

挂载(当组件实例被创建并插入DOM中)的时候

生命周期的调用顺序

  1. 构造函数 constructor() 初始化状态 static;

getDerivedStateFromProps(nextprops,prevstate) 根据新的属性(props)生成新的状态(state) 参数是新的属性props和老的状态,此生命周期不常用.

  1. render() 把虚拟DOM变成真实DOM并插入到DOM元素中;
  2. componentDidMount(); DOM挂载完成.
  • 组件的渲染顺序,父组件先渲染(父组件render之后) => 子组件开始渲染 => 子组件挂载完成之后(componentDidMount)父组件最后挂载完成(componentDidMount).
import React from 'react'import { render } from 'react-dom'class App extends React.Component {    constructor() {        super()        this.state = { num: 1 }        console.log('1 初始化挂载');
    }    add = () => {        this.setState({ num: this.state.num + 1 })    }    UNSAFE_componentWillMount() { //即将废弃        console.log('2.5 组件即将挂载--即将废弃');    }    componentDidMount() {        console.log('3 挂载完成');    }    render() {        console.log('2 render 渲染');        return (            <div>                <Child num={this.state.num} />                <button onClick={this.add}>点击父组件加一</button>            </div>        );    }}class Child extends React.Component {    constructor() {        super();        this.state = {            n: 1        }        console.log('1.1 子组件 初始化constructor');    }    //根据新的属性生成新的状态    // 返回null 不更新任何状态    static getDerivedStateFromProps(nextprops, prevstate) {        //参数是新的props属性        console.log('1.2 getDerivedStateFromProps');        let { num } = nextprops;        if (num === 2) {            return {                n: prevstate.n + 2            }        }        return null
    }    componentDidMount() {        console.log('1.4 子组件 挂载完成');    }    render() {        console.log('1.3 子组件 渲染');        return <div>            我是子组件            {this.state.n}            <br />            父组件传过来的props是{this.props.num}        </div>
    }}render(<App />, document.getElementById('root'))

更新#

组件的 propsstate 发生变化时会触发更新。

组件更新的生命周期调用顺序如下:

  1. static getDerivedStateFromProps()

  2. shouldComponentUpdate()

    • 如果 shouldComponentUpdate返回的是false 则不在继续
    • 返回true 会继续第3步
  3. render()

  4. getSnapshotBeforeUpdate() 获取DOM更新前的快照

  5. componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行此方法。

import React from 'react'import { render } from 'react-dom'class App extends React.Component {    constructor() {        super()        this.state = { num: 1 }        console.log('1 初始化挂载');    }    add = () => {        this.setState({ num: this.state.num + 1 })    }    UNSAFE_componentWillMount() { //即将废弃        console.log('2.5 组件即将挂载--即将废弃');    }    shouldComponentUpdate(nextProps, nextState) {        // 询问组件是否需要更新,如果返回true 就返回更新,返回false不更新        //参数 是新的属性和新的状态        console.log(nextProps);        console.log(nextState);        console.log('更新1.0 询问组件是否需要更新 shouldComponentUpdate');        return true        // return false    }    componentDidMount() {        console.log('3 挂载完成');    }    componentDidUpdate() {        console.log('更新2.0 更新完成');    }
    render() {        console.log('2 render 渲染');        return (            <div>                {/* <Child num={this.state.num} /> */}                {this.state.num}                <button onClick={this.add}>点击父组件加一</button>            </div>        );    }}class Child extends React.Component {    constructor() {        super();        this.state = {            n: 1        }        console.log('1.1 子组件 初始化constructor');    }    //根据新的属性生成新的状态    // 返回null 不更新任何状态    static getDerivedStateFromProps(nextprops, prevstate) {        //参数是新的props属性        console.log('1.2 getDerivedStateFromProps');        let { num } = nextprops;        if (num === 2) {            return {                n: prevstate.n + 2            }        }        return null    }    componentDidMount() {        console.log('1.4 子组件 挂载完成');    }    render() {        console.log('1.3 子组件 渲染');        return <div>            我是子组件            {this.state.n}            <br />            父组件传过来的props是{this.props.num}        </div>
    }}render(<App />, document.getElementById('root'))
  • constructor 👉 getDerivedStateFromProps(静态方法)👉 shouldComponentUpdate(询问是否需要更新) 👉 不需要(中断)
  • constructor 👉 getDerivedStateFromProps(静态方法)👉 shouldComponentUpdate(询问是否需要更新) 👉 需要 👉 render(渲染) 👉 getSnapshotBeforeUpdate(获取到更新的dom) 👉 componentDidUpdate
  • componentDidUpdate() 会在更新后会被立即调用。但首次挂载渲染不会执行此方法。

卸载#

当组件从 DOM 中移除时会调用,方法如下:

  • componentWillUnmount()componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除本地存储状态。
import React from 'react'import { render } from 'react-dom'
class App extends React.Component {    constructor() {        super()        this.state = { num: 1 }    }    add = () => {        this.setState({ num: this.state.num - 1 })    }    render() {        return <div >            {this.state.num && <Children />}            {this.state.num}            <button onClick={this.add}>点击</button>        </div>    }}class Children extends React.Component {    componentWillUnmount() {        console.log('组件即将卸载');    }    render() {        return <div >            我是子组件        </div>    }}render(<App />, document.getElementById('root'))
  • 在生命周期的render阶段(Render及之前的生命周期) 纯净且不包含副作用。可能会被 React 暂停,中止或重新启动

    • construtor render 初始化状态和接收props参数
  • Pre-commit 阶段 可以读取 DOM。

    • getSnapshotBeforeUpdate
  • commit 阶段 可以使用 DOM,运行副作用,安排更新。(重点)

    • componentDidMount
    • componentDidUpdate
    • componentWillUnmount