React的生命週期函數

2022-08-31 18:03:08

概述

在React中,生命週期函數指的是元件在某一個時刻會自動執行的函數

constructor

 在類或元件建立的時候被自動執行,我們可以說它是生命週期函數,但它並不是React所特有的,所有的Es6物件都有這個函數,所以並不能說它是React的生命週期函數

初始

當資料發生變化時,render函數會被自動執行,符合我們對React生命週期函數的定義,所以它是React的生命週期函數,但在初始階段,並不會有任何的React生命週期函數被執行,但會執行constructor建構函式,進行元件資料的初始化、

import React,{Component} from 'react';

class Demo extends Component{
    constructor(props){
        console.log("初始化資料...");
        super(props);
        this.state = {};
    }
    render(){
        return (
            <div>Hello World</div>
        );
    }
}
export default Demo

掛載

頁面掛載階段,UNSAFE_componentWillMount 頁面即將render掛載在html前執行,以前叫做componentWillMount但React團隊認為這些生命週期函數經常被誤解和巧妙的濫用,會帶來潛在的問題,所以為他們加上了UNSAFE_字首,當然這裡的不安全不是指安全性,而是表示使用這些周期函數在未來的React版本中更有可能出現錯誤。即將掛載的函數執行完畢,會進行渲染掛載render,之後會執行componentDidMount函數,我們可以把完成掛載後的邏輯寫在這個函數上。記住,只有元件第一次渲染頁面才會執行mount

 

import React,{Component} from 'react';

class Demo extends Component{
    constructor(props){
        console.log("初始化資料...");
        super(props);
        this.state = {};
    }
    UNSAFE_componentWillMount(){
        console.log('UNSAFE_componentWillMount');
    }

    render(){
        console.log('render');
        return (
            <div>Hello World</div>
        );
    }

    componentDidMount(){
        console.log('componentDidMount');
    }
}
export default Demo

 更新

資料更新階段,state或props發生變化,頁面會重新渲染。state會在更新前先執行shouldComponentUpdate生命週期函數,這個函數比較特殊,它需要有一個返回值,true或者false,控制頁面是否需要重新重新渲染,如果僅僅是資料發生變化,我們可以返回false,那麼之後的生命週期函數都不會執行,這樣可以有效的提升我們元件更新的效率。返回true後,會執行UNSAFE_componentWillUpdate函數做更新前的準備,在執行render進行頁面的重新渲染,渲染完畢後執行componentDidUpdate函數

import React,{Component} from 'react';

class Demo extends Component{
    constructor(props){
        console.log("初始化資料...");
        super(props);
        this.handleClickTest = this.handleClickTest.bind(this);
        this.state = {
            number:1
        };
    }

    handleClickTest(){
        const number = this.state.number + 1;
        this.setState({
            number
        });
    }

    UNSAFE_componentWillMount(){
        console.log('UNSAFE_componentWillMount');
    }

    render(){
        console.log('render');
        return (
            <div onClick={this.handleClickTest}>Hello World</div>
        );
    }

    componentDidMount(){
        console.log('componentDidMount');
    }
    //更新前執行
    shouldComponentUpdate(){
        console.log('shouldComponentUpdate');
        return true;
    }

    UNSAFE_componentWillUpdate(){
        console.log('componentWillUpdate');
    }

    componentDidUpdate(){
        console.log('componentDidUpdate')
    }

}
export default Demo

 componentWillReceiveProps生命週期函數,只有一個元件接收props或者說當一個元件是子元件接收props的時候,它才會被執行,所以我們需要定義一個子元件接收父元件傳值

import React,{Component,Fragment} from 'react';
import Demo2 from './Demo2';
class Demo extends Component{
    constructor(props){
        console.log("初始化資料...");
        super(props);
        this.handleClickTest = this.handleClickTest.bind(this);
        this.state = {
            number:1
        };
    }

    handleClickTest(){
        const number = this.state.number + 1;
        this.setState({
            number
        });
    }

    UNSAFE_componentWillMount(){
        console.log('UNSAFE_componentWillMount');
    }

    render(){
        console.log('render');
        return (
            <Fragment>
                <div onClick={this.handleClickTest}>Hello World</div>
                <Demo2 number={this.state.number}/>
            </Fragment>
        );
    }

    componentDidMount(){
        console.log('componentDidMount');
    }
    //更新前執行
    shouldComponentUpdate(){
        console.log('shouldComponentUpdate');
        return true;
    }

    UNSAFE_componentWillUpdate(){
        console.log('componentWillUpdate');
    }

    componentDidUpdate(){
        console.log('componentDidUpdate')
    }
    //元件從頁面中移除前自動執行
    componentWillUnmount(){

    }



}
export default Demo

 子元件Demo2

import React,{Component} from 'react';

class Demo2 extends Component{
    componentWillReceiveProps(){
        console.log('componentWillReceiveProps');
    }

    render(){
        const {number} = this.props;
        return (<div>{number}</div>);
    }
}
export default Demo2;

當子元件接收引數發生變化時,就會執行componentWillReceiveProps函數,然後執行shouldComponentUpdate函數,返回值為true時依次執行componentWillUpdate,render,componentDidUpdate

移除

當元件從頁面移除時自動執行componentWillUnmount函數,我們先定義一個路由

import React from 'react';
import ReactDom from 'react-dom';
import TodoList from './TodoList';
import {BrowserRouter,Routes,Route} from 'react-router-dom';
import ButtonTest from './ButtonTest';
import NewButton from './NewButton';
import Demo from './Demo';
class Entry extends React.Component{
    render(){
        return (
            <BrowserRouter>
                <Routes>
                    {/*{<Route path='/todoList' element={<TodoList/>}/>}*/}
                    {<Route path='/buttonTest' element={<ButtonTest/>}/>}
                    {<Route path='/newButton' element={<NewButton/>}/>}
                    <Route path='/Demo' element={<Demo/>}/>
                </Routes>
            </BrowserRouter>
        )
    }
}

ReactDom.render(<Entry/>,document.getElementById('root'));

 

從button元件跳轉到list元件,button從頁面移除時可觀察到自動執行了componentWillUnmount函數

import React,{Component} from 'react';
import { Button } from 'antd';
import {Link} from 'react-router-dom';
class NewButton extends Component{
    render(){
        return (
            <Link to='/buttonTest'>
                <Button type="primary">Primary</Button>
            </Link>
        );
    }
    //元件從頁面中移除前自動執行
    componentWillUnmount(){
        console.log('componentWillUnmount-----------');
    }
}
export default NewButton;
import React,{Component} from 'react';
import { List, Avatar } from 'antd';

const data = [
    {
        title: 'Ant Design Title 1',
    },
    {
        title: 'Ant Design Title 2',
    },
    {
        title: 'Ant Design Title 3',
    },
    {
        title: 'Ant Design Title 4',
    },
];

class ButtonTest extends Component{

    render(){
        return (
            <List
                itemLayout="horizontal"
                dataSource={data}
                renderItem={item => (
                    <List.Item>
                        <List.Item.Meta
                            avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
                            title={<a href="https://ant.design">{item.title}</a>}
                            description="Ant Design, a design language for background applications, is refined by Ant UED Team"
                        />
                    </List.Item>
                )}
            />
        );
    }
}

export default ButtonTest;

執行結果