1. 程式人生 > >詳解React生命週期及鉤子函式

詳解React生命週期及鉤子函式

父元件

import React , {Component} from 'react'
import Son from './Son'

class Father extends Component {
    constructor(props){
        // 可以繫結this 設定props 根據屬性設定狀態  給方法繫結this
        super(props)
        console.log('Father : constructor')
        this.state = {
            color : 'blue'
        }
    }
    componentWillMount(){
        // 修改state  不會觸發update  可以做初始資料的獲取
        console.log('Father : componentWillMount')
        // this.state = {
        //     color : 'blue'
        // }  // color值被改變 但是會報錯,建議用setState
    }
    render(){
        // 父元件在render過程中會觸發子元件的初始化階段,當所有的元件都轉載完成後,父元件才會執行didmount
        console.log('Father : render')
        return (
           <div>
               <button className='Btn' style = {{color:this.state.color}}
                    onClick = {()=> this.changeColor('red')}
               >變成紅色</button>
               <button>變成紅色</button>
               <button onClick = {()=> this.changeColor('yellow')}>變成黃色</button>
               
              {this.state.color !== 'yellow' && <Son color={this.state.color}/> }
           </div>
        )
    }
    changeColor(color){
        this.setState({color})
    }
    
    componentDidMount(){
        // 可以操作真實的DOM  初始化結束
        console.log('Father : componentDidMount',document.querySelector('.Btn'))
    }
    // 當元件componentDidMount之後,就進入執行中階段,此時只要資料(props,state)變化就會觸發對應的生命週期鉤子函式
}

export default Father

子元件

import React , {Component} from 'react'

class Son extends Component {
    constructor(props){
        super(props)
        this.state = {
            style:{
                width:'200px',
                height:'200px',
                backgroundColor:this.props.color   
            }
        }
        console.log('Children : constructor');
    }
    
    componentWillMount(){
        console.log('Children : componentWillMount')
    }
    render(){
        console.log('Childern : render')
        return (
            <div style={this.state.style}>
            </div>
        )
    }
    componentDidMount(){
        console.log('Children : componentDidMount ')
    }

    // 當元件componentDidMount之後,就進入執行中階段,此時只要資料(props,state)變化就會觸發對應的生命週期鉤子函式
    // componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate
    componentWillReceiveProps(props){
        // 這個鉤子函式中,新的屬性還沒掛載到this上,引數props是最新的props
        console.log('Children : componentWillReceiveProps',arguments)
        this.setState((prevState,props)=>{
            console.log(prevState,props,'this.setState函式寫法中接收的引數') // props 是最新的props
            let newstyle = { ...prevState.style }
            newstyle.backgroundColor = props.color
            return {style:newstyle}
        })
    }
    // 當屬性或者狀態變化後都會執行,需要返回true和false,預設返回true,控制是否執行下面的鉤子函式(是否重新渲染)
    shouldComponentUpdate(props, state){
        // 此時,最新的屬性和最新的狀態依然沒有掛載到this上,需要從函式中接收
        console.log('Children:shouldComponentUpdate',arguments);
        return true;
    }
    componentWillUpdate(props, state){
         // 此時,最新的屬性和最新的狀態依然沒有掛載到this上,需要從函式中接收 沒什麼作用
        console.log('Children:componentWillUpdate',arguments)
    }
    componentDidUpdate (prevprops, prevstate) {
        // 在這裡可以得到重新渲染後的dom
        if ( prevprops.color !== this.props.color ) {
            // 此次元件rerender是因為color變化
        }
        console.log('Children:componentDidUpdate')
    }

    componentWillUnmount () {
        // 當元件被銷燬的時候會執行這個鉤子函式
        console.log('Children:componentWillUnmount')
    }
}

export default Son
初始渲染

進入頁面的初始樣子

注意:父元件在render過程中會觸發子元件的初始化階段,當所有的子元件都裝載(compoentDidMount)完成後,父元件才會執行自己的componentDidMount

點選變成紅色按鈕後

點選變成紅色按鈕後

當元件componentDidMount之後,就進入執行中階段,此時只要資料(props,state)變化就會觸發對應的生命週期鉤子函式。
會依次執行 componentWillReceiveProps->shouldComponentUpdate(scu)->componentWillUpdate->rende->componentDidUpdate

點選變成黃色按鈕後 銷燬子元件

在這裡插入圖片描述

當元件銷燬後會執行元件的 componentWillMount 這個鉤子函式。
注意在React中元件銷燬的時候連帶dom一起消失的,所以沒有銷燬後的鉤子