1. 程式人生 > >010_React-組件的生命周期詳解

010_React-組件的生命周期詳解

完成 結構 highlight 歡迎信息 cloud IT log 函數 協作

ReactJS 的核心思想是組件化,即按功能封裝成一個一個的組件,各個組件維護自己的狀態和 UI,當狀態發生變化時,會自定重新渲染整個組件,多個組件一起協作共同構成了 ReactJS 應用。

為了能夠更好的創建和使用組件,我們首先要了解組件的生命周期。

一、組件的生命周期

組件在整個 ReactJS 的生命周期中,主要會經歷這4個階段:創建階段、實例化階段、更新階段、銷毀階段。下面對各個階段分別進行介紹。 技術分享圖片

1,創建階段

  • 該階段主要發生在創建組件類的時候,即調用 React.createClass 時觸發。
  • 這個階段只會觸發一個 getDefaultProps 方法,該方法返回一個對象並緩存起來。然後與父組件指定的 props 對象合並,最後賦值給 this.props 作為該組件的默認屬性。
props屬性介紹:
1,props 是一個對象,是組件用來接收外面傳來的參數的。
2,組件內部是不允許修改自己的 props 屬性,只能通過父組件來修改。上面的 getDefaultProps 方法便是處理 props 的默認值的。

2,實例化階段

該階段主要發生在實例化組件類的時候,也就是該組件類被調用的時候觸發。這個階段會觸發一系列的流程,按執行順序如下: (1)getInitialState:初始化組件的 state 的值。其返回值會賦值給組件的 this.state 屬性。 (2)componentWillMount:根據業務邏輯來對 state 進行相應的操作。 (3)render:根據 state 的值,生成頁面需要的虛擬 DOM 結構,並返回該結構。 (4)componentDidMount:對根據虛擬 DOM 結構而生的真實 DOM 進行相應的處理。組件內部可以通過 ReactDOM.findDOMNode(this) 來獲取當前組件的節點,然後就可以像 Web 開發中那樣操作裏面的 DOM 元素了。 state屬性介紹:
它是用來存儲組件自身需要的數據。它是可以改變的,它的每次改變都會引發組件的更新。這也是 ReactJS 中的關鍵點之一。
即每次數據的更新都是通過修改 state 屬性的值,然後 ReactJS 內部會監聽 state 屬性的變化,一旦發生變化,就會觸發組件的 render 方法來更新 DOM 結構。

3,更新階段

這主要發生在用戶操作之後或者父組件有更新的時候,此時會根據用戶的操作行為進行相應得頁面結構的調整。這個階段也會觸發一系列的流程,按執行順序如下:

(1)componentWillReceiveProps:當組件接收到新的 props 時,會觸發該函數。在改函數中,通常可以調用 this.setState 方法來完成對 state 的修改。 (2)shouldComponentUpdate:該方法用來攔截新的 props 或 state,然後根據事先設定好的判斷邏輯,做出最後要不要更新組件的決定。 (3)componentWillUpdate:當上面的方法攔截返回 true 的時候,就可以在該方法中做一些更新之前的操作。 (4)render:根據一系列的 diff 算法,生成需要更新的虛擬 DOM 數據。(註意:在 render 中最好只做數據和模板的組合,不應進行 state 等邏輯的修改,這樣組件結構更加清晰) (5)componentDidUpdate:該方法在組件的更新已經同步到 DOM 中去後觸發,我們常在該方法中做一 DOM 操作。

4,銷毀階段

  • 這個階段只會觸發一個叫 componentWillUnmount 的方法。
  • 當組件需要從 DOM 中移除的時候,我們通常會做一些取消事件綁定、移除虛擬 DOM 中對應的組件數據結構、銷毀一些無效的定時器等工作。這些事情都可以在這個方法中處理。

二、完整的樣例

下面通過一個簡單的歡迎信息組件,來演示組件各個環節的運作流程。同時這裏把組件整個生命周期中所有會觸發的方法都列出來了。

技術分享圖片

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>hangge</title>
    <script type="text/javascript" src="./node_modules/react/dist/react.js"></script>
    <script type="text/javascript" src="./node_modules/react-dom/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
    <script type="text/babel">
        var Welcome = React.createClass({
            /* 1.創建階段 */
            //在創建類的時候被調用
            getDefaultProps: function() {
                console.log("getDefaultProps");
                return {};
            },

            /* 2.實例化階段 */
            //獲取this.state的默認值
            getInitialState: function() {
                console.log("getInitialState");
                return {name: "hangge.com"};
            },
            //組件將要加載,在render之前調用此方法
            componentWillMount: function() {
                //業務邏輯的處理都應該放在這裏,比如對state的操作等
                console.log("componentWillMount");
            },
            //渲染並返回一個虛擬DOM
            render: function() {
                console.log("render");
                return (
                    <div>歡迎訪問: {this.state.name}</div>
                );
            },
            //組件完成加載,在render之後調用此方法
            componentDidMount: function() {
                //在該方法中,ReactJS會使用render方法返回的虛擬DOM對象來創建真實的DOM結構
                console.log("componentDidMount");
                var node = ReactDOM.findDOMNode(this);
                console.log(node);
            },

            /* 3.更新階段 */
            //該方法發生在this.props被修改或父組件調用setProps()方法之後
            componentWillReceiveProps: function() {
                console.log("componentWillRecieveProps");
            },
            //是否需要更新
            shouldComponentUpdate: function() {
                console.log("shouldComponentUpdate");
                return true;
            },
            //將要更新
            componentWillUpdate: function() {
                console.log("componentWillUpdate");
            },
            //更新完畢
            componentDidUpdate: function() {
                console.log("componentDidUpdate");
            },

            /* 4.銷毀階段 */
            //銷毀時會被調用
            componentWillUnmount: function() {
                console.log("componentWillUnmount");
            },
        });
        ReactDOM.render(<Welcome />, document.getElementById(‘example‘));
    </script>
</head>
<body>
    <div id="example"></div>
</body>
</html>

  技術分享圖片

Reference:http://www.hangge.com/blog/cache/detail_1473.html

010_React-組件的生命周期詳解