react教程 — 组件的生命周期 和 执行顺序

一、组件执行的生命周期:                  参考  https://www.cnblogs.com/soyxiaobi/p/9559117.html  或  https://www.cnblogs.com/kdcg/p/9182393.html(含生命周期函数 传进来的参数)

  1、初始没有改变state、props 的生命周期:

    constructor、componentWillMount、render 、【子组件对应这4个周期函数】、componentDidMount  依次执行

  2、改变 state 后的生命周期:

    a、父组件的 state 改变:

      shouldComponentUpdate、componentWillUpdate、render、【子组件的 componentWillReceiveProps、子组件对应父组件这4个周期函数】、componentDidUpdate

      父组件的的state改变,会引起子组件 state 相关的生命周期函数运行。

    b、子组件的 state 改变:

      shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate

      子组件的state改变,不会引起父组件的变化。

  3、改变 props 后的 生命周期:【props改变,不会引起父子组件的任何变化,state变化才引起子组件的变化

    父组件传递给子组件的props改变,不会引起任何变化。只有父组件state改变,父组件render函数运行,所有子组件递归更新。

    所以父组件传递给子组件的props值,一般使用state的值,不然给子组件的props值改变了,但是没有办法传递到子组件中,得等触发了父组件的render函数,才能把数据传递给子组件。

    父组件的 state 设置,都会触发子组件的 componentWillReceiveProps 生命周期函数,且把函数参数是props值。

代码演示:

父组件

import React from 'react'
import Two from './component/two'

class DataFlow extends React.Component{
    constructor(props){
        super(props)
        console.log('constructor');
    }
    state = {
        name: 'ydfd'
    }
    componentWillMount(){ // 渲染前的时刻,即 render前执行
        console.log('componentWillMount');  
    }
    componentDidMount(){ // 渲染后的时刻,即 render后执行
        console.log('componentDidMount')
    }
    componentWillReceiveProps (){
        console.log('componentWillReceiveProps')
    }
    componentWillUnmount(){ // 组件的卸载
        console.log('componentWillUnmount')
    }
    // 组件自身的 state 更新了,那么会依次执行  shouldComponentUpdate 、 componentWillUpdate 、render 和  componentDidUpdate 。
    shouldComponentUpdate(){ // 是一个特别的方法,当方法返回  false 的时候,组件不再向下执行生命周期方法。
        console.log('shouldComponentUpdate')
        return true
    }
    componentWillUpdate(){ // 更新过程中渲染前的时刻,不能在这里执行  setState
        console.log('componentWillUpdate');
    }
    componentDidUpdate(){ // 更新过程中渲染后的时刻
        console.log('componentDidUpdate');
    }
    click(){
        this.setState({
            name: 'yuu'
        })
    }

    render(){
        console.log('顶级组件 render 方法')
        return (
            <div className="fatherBox">
                <h1>顶层组件</h1>
                    <p>{this.state.name}</p>
                <button onClick={this.click.bind(this)}>触发事件</button>
                <Two name={this.state.name}></Two>
            </div>
        )
    }
}

export default DataFlow;

子组件

import React from 'react'

class Two extends React.Component{
    constructor(props){
        super(props)
        console.log('child === constructor');
    }
    componentWillMount(){ // 渲染前的时刻,即 render前执行
        console.log('child === componentWillMount');  
    }
    componentDidMount(){ // 渲染后的时刻,即 render后执行
        console.log('child === componentDidMount')
    }
    componentWillReceiveProps (newProps){
        console.log('child === componentWillReceiveProps',newProps)
    }
    componentWillUnmount(){ // 组件的卸载
        console.log('child === componentWillUnmount')
    }
    // 组件自身的 state 更新了,那么会依次执行  shouldComponentUpdate 、 componentWillUpdate 、render 和  componentDidUpdate 。
    shouldComponentUpdate(){ // 是一个特别的方法,当方法返回  false 的时候,组件不再向下执行生命周期方法。
        console.log('child === shouldComponentUpdate')
        return true
    }
    componentWillUpdate(){ // 更新过程中渲染前的时刻,不能在这里执行  setState
        console.log('child === componentWillUpdate');
    }
    componentDidUpdate(){ // 更新过程中渲染后的时刻
        console.log('child === componentDidUpdate');
    }
    render(){
        console.log('二级组件 render 方法')
        return (
            <div className="twoBox">
                <h2>二级组件</h2>
                <p>{this.props.name}</p>
            </div>
        )
    }
}

export default Two;

二、生命周期 图示: https://www.jianshu.com/p/514fe21b9914

  a、组件初始化阶段:

    constructor

  b、组件的挂载(Mounting)阶段:

    componentWillMount:【新版已经改名】

    render:

    componentDidMount:组件挂载到DOM后调用,且只会被调用一次

  c、组件的更新(update)阶段:

    a、

三、各生命周期 中 设置 调用 setState设置  state 的结果:https://www.jianshu.com/p/e09cbecca1d1

  1、constructor:这里不会使用 setState 设置state 值,直接初始化。

  2、componentWillMount:  只是把state合并到初始化状态中,而根本不会触发render ;在这里更新state,就等同于直接写在this.state中,所以,在此生命周期中的setState根本没有意义

  3、shouldComponentUpdate:  禁止使用。

  4、componentWillUpdate:     禁止使用

  5、render :render 中不能 setState 设置state,不然就会报错。   render 是  props、state 的纯函数。

  6、componentDidMount:正常使用。  初始化时传递给子组件的数据,不要在 这里设置。不然,初始化时,有效数据并没有子组件,而是更新时传递过去。

  总结:

    生命周期中setState的使用情况:

        无意义使用:componentWillMount,componentWillUnmount;

        有条件使用:componentDidUpdate;

        禁止使用:componentWillUpdate,shouldComponentUpdate;

        正常使用:componentWIllReceiveProps,componentDidMount。

    生命周期中setState是否触发更新:

        componentWillMount和componentWillReceiveProps中,setState会被react内部处理,而不触发render;

        其他生命周期均正常出发更新渲染。


上面讲的是class组件的执行过程,函数组件是没有生命周期的。但是函数组件 的 父组件,render执行,子组件都会重新渲染的,即子组件的组件函数重新执行。

将上面的子组件改成 函数组件

import React from 'react';

function Test(){
    console.log('函数组件内');
    return (
        <div id="home-container">
        <button onClick={testClick}>
             子组件按钮
     </button>
</div>
    )
}
export default Test;

父组件的state改变,会引起子组件的Test函数重新执行。

原文地址:https://www.cnblogs.com/wfblog/p/11842622.html