1. 程式人生 > >React——元件基本結構及其生命週期

React——元件基本結構及其生命週期

元件基本結構

建構函式constructor

  • 功能:子級繼承父級的時候,通過建構函式獲取父級的屬性和方法,並通過super()傳遞的引數進行構造。
  • constructor(){super()}
  • 元件建構函式會在元件例項的時候最先呼叫!
 constructor() {
     super()
     console.log('constructor 初始化資料')
 }

元件

  • 定義了元件繼承於React的基本元件物件,一定要有自己的元件用於例項渲染。
  • 元件通過render()方法渲染,返回一個html格式的元件以供渲染。
  • 元件必須要用一個容器(div)包裹,不等各個元素節點都暴露在外面。
  • 元件分為靜態元件和有狀態元件。有狀態元件通過資料或邏輯控制組件裡的內容顯示,這些內容用state和setstate控制。
  • 基本格式:
render() {
    console.log('渲染')
    return (
        <div>
            <h2>{"大括號裡可以寫js程式碼"}</h2>
            <h2>Hello word</h2>
        </div>
    );
}

生命週期

import React, {
    Component
} from 'react';


class MyComponent extends Component {
    constructor() {
        super()
        this.state = {
            msg: 'Hello World'
        }
        console.log('constructor 初始化資料')
        this.handleClick = this.handleClick.bind(this)
    }
    // 元件將要載入
componentWillMount() { // 請求資料 非同步操作 console.log('componentWillmount 元件將要載入') } // 元件載入完成 componentDidMount() { console.log('componentDidMount 元件載入完成') } //////////////////////////////////////// // 執行中階段(更新階段) componentWillReceiveProps(nextProps) { console.log('componentWillReceiveProps 將要接收父元件傳來的props', nextProps) } // 元件是不是應該更新 預設是返回true false shouldComponentUpdate() { console.log('shouldComponentUpdate 元件是不是應該更新') return true; } // 元件將要更新 componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate 元件將要更新', nextProps, nextState) } // 更新完成 componentDidUpdate() { console.log('componentDidUpdate 更新完成') } // 即將銷燬 componentWillUnmount() { console.log('componentWillUnmount 即將銷燬') } handleClick() { this.setState({ msg: 'new Hello World' }) } // 渲染 render() { console.log('渲染') return ( <div> <h2>{this.state.msg}</h2> <h2>{this.props.abc}</h2> <input type="button" defaultValue='更新資料' onClick={this.handleClick} /> </div> ); } } class App extends Component { constructor() { super(); this.state = { data: 'old props', onOff: true } this.changeProps = this.changeProps.bind(this) this.toggleChild = this.toggleChild.bind(this) } // 要進入第二階段(更新階段) 資料在發生變化 changeProps() { this.setState({ data: 'new props 123456', }) } toggleChild() { this.setState({ onOff: !this.state.onOff }) } render() { return ( <div> { this.state.onOff ? <MyComponent abc={this.state.data}></MyComponent> : '' } <input type="button" defaultValue='更新props' onClick={this.changeProps} /> <input type="button" defaultValue='銷燬元件' onClick={this.toggleChild} /> </div> ); } } export default App;

執行時沒有操作過程的頁面

在這裡插入圖片描述

  • 元件生命週期包含:即將載入、載入完成、更新、是否更新、即將更新、更新完成、即將銷燬。

載入

即將載入:componentWillMount

  • 在元件掛載之前呼叫,且全域性只調用一次。如果在這個鉤子裡可以setState,render後可以看到更新後的state,不會觸發重複渲染。該生命週期可以發起非同步請求,並setState。
componentWillMount() {
    // 請求資料 非同步操作
    console.log('componentWillmount 元件將要載入')
}

已經載入:componentDidMount

  • 元件第一次渲染完成,此時dom節點已經生成。可以在這裡呼叫ajax請求,進行進一步的資料互動,返回資料setState後元件會重新渲染。
componentDidMount() {
    console.log('componentDidMount 元件載入完成')
}
  • 至此,宣告週期的第一個階段完成,元件的demo出現在網頁,如果有資料互動,那麼第一次的資料已經初始化完成。

更新

該不該更新:shouldComponentUpdate

  • 用於控制組件該不該更新的函式,在父元件更新引起子元件重新渲染的情況下使用較多。
// 元件是不是應該更新  預設是返回true  false
shouldComponentUpdate() {
    console.log('shouldComponentUpdate 元件是不是應該更新')
    return true;
}

即將更新:componentWillUpdate(nextProps, nextState)

  • shouldComponentUpdate返回true以後,元件進入重新渲染的流程,進入componentWillUpdate,這裡同樣可以拿到nextProps和nextState,多用於資料反饋處理等。
// 元件將要更新
componentWillUpdate(nextProps, nextState) {
    console.log('componentWillUpdate 元件將要更新', nextProps, nextState)
}

更新完成:componentDidUpdate

元件接收到資料並渲染完成時觸發。

元件更新完畢後,react只會在第一次初始化成功會進入componentDidmount,之後每次重新渲染後都會進入這個生命週期,這裡可以拿到prevProps和prevState,即更新前的props和state。

// 更新完成
componentDidUpdate(prevProps, prevState) {
    console.log('componentDidUpdate 更新完成', prevProps, prevState)
}
  • demo點選更新資料結果:

在這裡插入圖片描述

更新階段或者說執行中階段:componentWillReceiveProps(nextProps)

  • 在父元件呼叫子元件,給子元件更新資料的時候觸發該方法,nextProps即是傳遞進來的資料。

父元件

//父元件
class App extends Component {
    constructor() {
        super();
        this.state = {
            data: 'old props',
            onOff: true
        }
        this.changeProps = this.changeProps.bind(this)
        this.toggleChild = this.toggleChild.bind(this)
    }
    // 要進入第二階段(更新階段) 資料在發生變化
    changeProps() {
        this.setState({
            data: 'new props 123456',

        })
    }
    toggleChild() {
        this.setState({
            onOff: !this.state.onOff
        })
    }
    render() {
        return (
            <div>
                {
                    this.state.onOff ? <MyComponent abc={this.state.data}></MyComponent> : ''
                }
                <input type="button" defaultValue='更新props' onClick={this.changeProps} />
                <input type="button" defaultValue='銷燬元件' onClick={this.toggleChild} />
            </div>
        );
    }
}

點選更新props按鈕的時候,將觸發App父元件裡的input,input點選觸發changeState方法,state的資料被更改,由於元件基於資料驅動,那麼涉及到state的元件都會被更新,則,子元件MyComponent會被更新,MyComponent更新時收到父元件傳遞Props影響觸發執行時態宣告周期函式。

同時,傳遞過來的資料也觸發了更新狀態的生命週期函式。

在這裡插入圖片描述

即將銷燬

即將銷燬:componentWillUnmount()

  • 銷燬元件後demo以及相關的事件等都會被銷燬,這就是元件的強大之處,對於web效能有很大的改善!
  1. clear你在組建中所有的setTimeout,setInterval
  2. 移除所有組建中的監聽 removeEventListener
  3. 也許你會經常遇到這個warning:
// 即將銷燬
componentWillUnmount() {
    console.log('componentWillUnmount 即將銷燬')
}

在這裡插入圖片描述