React生命周期详解

React生命周期详解

React严格定义了组件的生命周期会经历如下三个过程:

  • 装载过程(Mount),组件第一次在DOM树渲染的过程。
  • 更新过程(Update),当组件被重新渲染的过程。
  • 卸载过程(Unmount),组件重DOM树中删除的过程。

执行这3个过程的调用函数就是声明周期函数。

装载过程

该过程会依次调用如下函数:

  • constructor():ES6类的构造函数(为了初始化state或绑定this
  • getInitialState():ES5中初始化state
  • getDefaultProps():ES5中初始化props。在ES6中使用defaultProps()方法。
  • componentWillMount():在组件被挂载前调用。只执行一次。
  • render():渲染组件,必须实现该方法。
  • componentDidMount():在组件装载后调用。这时已经生成了真实的DOM节点。只执行一次。

更新过程

当组件的props或者state改变时就会触发组件的更新过程。

更新过程会依次执行如下函数:

  • componentWillReceiveProps(nextProps):当父组件的render()方法执行后就会触发该方法。初始化时不调用。
  • shouldComponentUpdate(nextProps,nextState):当props改变或state改变时调用,初始化时不掉用,返回booleantrue表示继续执行render方法,fasle表示放弃本次渲染。
  • componentWillUpdate(nextProps,nextState):当shouldComponentUpdate返回true时调用,初始化不调用。
  • render():渲染组件。
  • componentDidUpdate(prevProps,prevState,snapshot):渲染完成后调用,初始化不调。prevPropsprevState是指组件更新前的propsstate

卸载过程

componentWillUnmount():将组件从DOM树移出,防止内存溢出。

React生命周期详解_第1张图片

实例演示

组件调用:

import React from 'react'
import App from './components/App.js'
import {render} from 'mirrorx'


// 启动 app,render 方法是加强版的 ReactDOM.render
render(<App/>, document.getElementById('root'))

组件定义:

import React from 'react'
import mirror, { actions, connect, render } from 'mirrorx'

// 声明 Redux state, reducer 和 action,
// 所有的 action 都会以相同名称赋值到全局的 actions 对象上
mirror.model({
    name: 'app',
    initialState: 0,
    reducers: {
        increment(state) { return state + 1 },
        decrement(state) { return state - 1 }
    },
    effects: {
        async incrementAsync() {
            await new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve()
                }, 1000)
            })
            actions.app.increment()
        }
    }
})

class App extends React.Component {

    constructor(props){
        super(props)
        console.log("---初始化组件---")
    }

    componentWillMount(){
        console.log("---组件挂载前---")
    }

    componentDidMount(){
        console.log("---组件挂载后---")
    }

    componentWillReceiveProps(nextProps){
        console.log("---父组件重新渲染---")
    }

    shouldComponentUpdate(nextProps,nextState){
        console.log("---组件接受到重绘状态---")
        if(this.props != nextProps || this.state != nextState)
        return true
    }
    
	componentWillUpdate(nextProps,nextState){
	    console.log("---组件即将重绘---")
	}

    componentDidUpdate(prevProps,prevState){
	    console.log("---组件重绘完成---")
	}


    render() {
        console.log("---组件渲染---")
        const props = this.props 
        return (
            <div>
                <h1>{props.count}</h1>
                {/* 调用 actions 上的方法来 dispatch action */}
                <button onClick={() => actions.app.decrement()} style={{ margin: "5px" }}>-</button>
                <button onClick={() => actions.app.increment()} style={{ margin: "5px" }}>+</button>
                {/* dispatch async action */}
                <button onClick={() => actions.app.incrementAsync()} style={{ margin: "5px" }}>+ Async</button>
            </div>
        )
    }
}

export default connect((state) => {
    return {
        count: state.app
    }
})(App)

页面效果

React生命周期详解_第2张图片

当页面刷新时,组件进行初始化价值,打印信息如下:

—初始化组件—
—组件挂载前—
—组件渲染—
—组件挂载后—

当点击+号时,组件进行更新操作,打印信息如下:

—父组件重新渲染—
—组件接受到重绘状态—
—组件即将重绘—
—组件渲染—
—组件重绘完成—

React 16.0版本修改

React 16.0之后的版本生命周期有所修改。

react 16版本提出了异步渲染的概念,对之前的生命周期有较大的影响。

componentDidCatch(error,info):该生命周期是React 16.0版本提出的,用于捕获render阶段出现的错误,并不影响之前的生命周期。

static getDerivedStateFromProps(props, state):render()之前调用,它应该返回一个对象来更新状态,或者返回null来不更新任何内容。组件创建和更新时均将调用。在React 16.3提出,16.4版本修复,属于新增生命周期。

getSnapshotBeforeUpdate(prevProps, prevState):在render之后componentDidUpdate之前调用,可以读取dom结构,但无法操作dom元素,其返回的任何值都将传递给componentDidUpdate

在React 17版本中将废弃componentWillMountcomponentWillReceivePropscomponentWillUpdate这3个方法,但也提供了带UNSAFE_componentWillMountUNSAFE_componentWillReceivePropsUNSAFE_componentWillUpdate作为兼容考虑,只是不提倡使用。

React生命周期详解_第3张图片

你可能感兴趣的:(React)