1. 程式人生 > 程式設計 >React元件的生命週期詳細描述

React元件的生命週期詳細描述

目錄
  • 一、什麼是生命週期
  • 二、裝載過程
    • 1、constructor
    • 2、render
    • 3、componentWillMount和componentDidMount
  • 三、更新過程
    • 1、componentWillReceiveProps(nextProps)
    • 2、shouldComponentUpdate(nextProps, nextState)
    • 3、componentWillUpdate和componentDidUpdate
    • 4、觸發render
  • 四、解除安裝過程
    • 五、生命週期流程
      • 1、第一次初始化渲染顯示: ReactDOM.render()
      • 2、每次更新 state: this.setState()
      • 3、移除元件: ReactDOM.unmouwww.cppcns.com
        ntComponentAtNode(containerDom)
    • 六、示例
      • 總結

        一、什麼是生命週期

        元件的生命週期就是React的工作過程,就好比人有生老病死,自然界有日月更替,每個元件在中也會有被建立、更新和刪除,如同有生命的機體一樣。

        React元件的生命週期可以分為三個過程

        • 裝載(掛載)過程(mount):就是元件第一次在DOM樹中渲染的過程。
        • 更新過程(update):元件被重新渲染的過程。
        • 解除安裝過程(unmount):元件從DOM中被移除的過程。

        二、裝載過程

        依次呼叫如下函式constructor、getInitialState、getDefaultProps、componentWillMount、render、componentDidMount。

        1、constructor

        就是ES6裡的建構函式,建立一個元件類的例項,在這一過程中要進行兩步操作:初始化state,繫結成員函式的this環境。

        2、render

        render是React元件中最為重要的一個函式。這是react中唯一不可忽略的函式,在render函式中,只能有一個父元素。render函式是一個純函式,它並不進行實際上的渲染動作,它只是一個X描述的結構,最終是由React來進行渲染過程,render函式中不應該有任何操作,對頁面的描述完全取決於this.state和this.props的返回結果,不能在render呼叫this.setState。

        • 有一個公式總結的非常形象 UI=render(data)

        3、componentWillMount和componentDidMount

        這兩個函式分別在render前後執行,由於這一過程通常只能在瀏覽器端呼叫,所以我們在這裡獲取非同步資料,而且在componentDidMount呼叫的時候,元件已經被裝載到DOM樹上了。

        三、更新過程

        簡單來說就是props和state被修改的過程,依次呼叫componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate。

        1、componentWillReceiveProps(nextProps)

        並不是只有在props發生改變的時候才會被呼叫,實際上只要是父元件的render函式被呼叫,render裡面被渲染的子元件就會被更新,不管父元件傳給子元件的props有沒有被改變,都會觸發子元件的componentWillReceiveProps過程,但是,this.setState方法的觸發過程不會呼叫這個函式,因為這個函式適合根據新的props的值來計算出是不是要更新內部狀態的state。

        2、shouldComponentUpdate(nextProps, nextState)

        這個函式的重要性,僅次於render,render函式決定了該渲染什麼,而shouldComponentUpdate決定了不需要渲染什麼,都需要返回函式,這一過程可以提高效能,忽略掉沒有必要重新渲染的過程。

        3、componentWillUpdate和componentDidUpdate

        和裝載過程不同,這裡的componentDidUpdate,既可以在瀏覽器端執行,也可以在伺服器端執行

        4、觸發render

        在react中,觸發render的有4條路徑。

        以下假設shouldComponentUpdate都是按照預設返回true的方式:

        (1) 首次渲染Initial Render。

        (2) 呼叫this.setState (並不是一次setState會觸發一次render,React可能會合並操作,再一次性進行render)。

        (3) 父元件發生更新(一般就是props發生改變,但是就算props沒有改變或者父子元件之間沒有資料交換也會觸發render)。

        (4) 呼叫this.forceUpdate。

        在這裡插入圖片描述

        注意:如果在shouldComponentUpdate裡面返回false可以提前退出更新路徑。

        四、解除安裝過程

        實際中很少用到,這裡只有一個componentWillUnmount,一般在componentDidMount裡面註冊的事件需要在這裡刪除。

        五、生命週期流程

        1、第一次初始化渲染顯示: ReactDOM.render()

        • constructor(): 建立物件初始化 state
        • componentWillMount() : 將要插入回撥
        • render() : 用於插入虛擬 DOM 回撥
        • componentDidMount() : 已經插入回撥

        2、每次更新 state: this.setState()

        • componentWillUpdate() : 將要更新回撥
        • render() : 更新(重新渲染)
        • componentDidUpdate() : 已經更新回撥

        3、移除元件: ReactDOM.unmountComponentAtNode(containerDom)

        • componentWillUnmount() : 元件將要被移除回撥

        六、示例

         <div id='container'></div>
            <script type="text/babel">
                class LifeCycle extends React.Component {
                    constructor(props) {
                        super(props);
                        alert("Initial render");
                        alert("constructor");
                        this.state = {str: "hello"};
                    }
                     componentWillMount() {
                        alert("componentWillMount");
                    }
                    componentDidMount() {
                        alert("componentDidMount");
                    }
                    componentWillReceiveProps(nextProps) {
                        alert("componentWillReceiveProps");
                    }
                    shouldComponentUpdate() {
                        alert("shouldComponentUpdate");
                        return true;        // 記得要返回true
                    }
                     componentWillUpdate() {
                        alert("componentWillUpdate");
                    }
                    componentDidUpdate() {
                        alert("componentDidUpdate");
                    }
                    componentWillUnmount() {
                        alert("componentWillUnmount");
                    }
                    setTheState() {
                        let s = "hello";
                        if (this.state.str === s) {
                            s = "HELLO";
                        }
                        this.setState({
                            str: s
                        });
                    }
                    forceItUpdate() {
                        this.forceUpdate();
                    }
                    render() {
                        alert("render");
                        return(
                            <div>
                                <span>{"Props:"}<h2>{parseInt(this.props.num)}</h2></span>
                                <br />
                                <span>{"State:"}<h2>{this.state.str}</h2></span>
                            </div>
                        );
                    }
                }
                class Container  extends React.Component {
                    constructor(props) {
                        super(props);
                        this.state = {
                            num: Math.random() * 100
                        };
                    }
                    propsChange() {
                        this.setState({
                            num: Math.random() * 100
                        });
                    }
                    setLifeCycleState() {
                        this.refs.rLifeCycle.setTheState();
                    }
                    forceLifeCycleUpdate() {
                        this.refs.rLifeCycle.forceItUpdate();
                    }
                    unmountLifeCycle() {
                        // 這裡解除安裝父元件也會導致解除安裝子元件
                        ReactDOM.unmountComponentAtNode(document.getElementById("container"));
                    }
                    parentForceUpdate() {
                        this.forceUpdate();
                    }
                    render() {
                        return (客棧
                            <div>
                                <a href=":;"  onClick={this.propsChange.bind(this)}>propsChange</a>
                                &nbsp;&nbsp;&nbsp;
                                <a href="script:;"  onClick={this.setLifeCycleState.bind(this)}>setState</a>
                                &nbsp;&nbsp;&nbsp;
                     http://www.cppcns.com           <a href="javascript:;"  onClick={this.forceLifeCycleUpdate.bind(this)}>forceUpdate</a>
                                &nbsp;&nbsp;&nbsp;
                                <a href="javascript:;"  onClick={this.unmountLifeCycle.bind(this)}>unmount</a>
                                &nbsp;&nbsp;&nbsp;
                                <a href="javascript:;"  onClick={this.parentForceUpdate.bind(this)}>parentForceUpdateWithoutChange</a>
                                <LifeCycle ref="rLifeCycle" num={this.state.num}></LifeCycle>
                            </div>
                        );
                    }
                }
                ReactDOM.render(
                    <Container></Container>,document.getElementById('container')
                );
            </script>
        

        總結

        本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!