react-native開發(fā)系列筆記 - 1.組件的生命周期

一個 React Native 組件從它被加載,到最終被卸載熄驼,會經(jīng)歷一個完整的生命周期蛤售。

在這個生命周期中,框架已經(jīng)為我們定義了一些生命周期函數(shù)喂江,用來處理在特定條件下 React Native 組件將要執(zhí)行的操作召锈,比如在某個時間進行數(shù)據(jù)初始化或進行網(wǎng)絡(luò)請求等。

一获询、組件的生命周期

組件的生命周期一般分為4個階段:創(chuàng)建階段涨岁、實例化階段運行(更新)階段銷毀階段筐付。下面對各個階段分別進行介紹卵惦。

1. 創(chuàng)建階段
  • 該階段主要發(fā)生在創(chuàng)建組件類的時候,在這個階段會初始化組件的屬性類型propTypes和默認值defaultProps瓦戚。當調(diào)用該組件時,只要看創(chuàng)建階段的屬性聲明丛塌,即可知道如何調(diào)用较解。
  • 在 ES6 中統(tǒng)一使用 static 成員來實現(xiàn)畜疾。
    // 聲明屬性類型
    static propTypes = {
        name: PropTypes.string,
    };

    // 聲明屬性默認值
    static defaultProps = {
        name: 'xiaowang'
    };

備注1:出于性能原因,propTypes類型僅在develop模式下進行檢查印衔,production環(huán)境下不檢查啡捶。
備注2:RN官方推薦以組件的方式來重用代碼,而不是繼承奸焙。所以瞎暑,在實際開發(fā)中,應(yīng)多封裝組件与帆,并寫清楚組件需要傳入的參數(shù)類型聲明了赌,方便調(diào)用。

2. 實例化階段

該階段主要發(fā)生在實例化組件的時候玄糟,創(chuàng)建組件勿她,準備渲染,渲染阵翎,渲染完成逢并。
調(diào)用的函數(shù)順序如下:

  • constructor:構(gòu)造函數(shù),對組件的狀態(tài)進行初始化郭卫。
  • componentWillMount:準備加載組件砍聊,可以做一些業(yè)務(wù)初始化工作或設(shè)置組件狀態(tài)。
  • render:生成頁面需要的DOM結(jié)構(gòu)贰军,并返回玻蝌。
  • componentDidMount: 組件加載成功并被成功渲染后執(zhí)行。一般講網(wǎng)絡(luò)請求等獲取數(shù)據(jù)比較耗時的操作放在這里進行谓形,保證UI渲染不出現(xiàn)錯誤灶伊。
3. 運行(更新)階段

該階段主要發(fā)生在用戶操作之后或者父組件有更新的時候,此時會根據(jù)用戶的操作行為進行相應(yīng)的頁面結(jié)構(gòu)的調(diào)整寒跳。這個階段也會觸發(fā)一系列的流程聘萨,按執(zhí)行順序如下:

  • componentWillReceiveProps:當組件接收到新的 props 時,會觸發(fā)該函數(shù)童太。在該函數(shù)中米辐,通常可以調(diào)用 this.setState 方法來完成對 state 的修改书释。
  • shouldComponentUpdate:該方法用來攔截新的 props 或 state翘贮,然后根據(jù)事先設(shè)定好的判斷邏輯,做出最后要不要更新組件的決定爆惧。
  • componentWillUpdate:當上面的方法攔截返回 true 的時候狸页,就可以在該方法中做一些更新之前的操作。
  • render:根據(jù)一系列的 diff 算法,生成需要更新的虛擬 DOM 數(shù)據(jù)芍耘。(注意:在 render 中最好只做數(shù)據(jù)和模板的組合址遇,不應(yīng)進行 state 等邏輯的修改,這樣組件結(jié)構(gòu)會更加清晰)
  • componentDidUpdate:該方法在組件的更新已經(jīng)同步到 DOM 中去后觸發(fā)斋竞,我們常在該方法中做 DOM 操作倔约。
4. 銷毀階段

該階段主要在組件銷毀的時候觸發(fā)。

  • componentWillUnmount:當組件要被從界面上移除時就會調(diào)用坝初〗#可以在這個函數(shù)中做一些相關(guān)的清理工作,例如取消計時器鳄袍、網(wǎng)絡(luò)請求以及移除通知監(jiān)聽等绢要。

流程圖;


生命周期流程圖.png

二畦木、生命周期函數(shù)詳細介紹

1. constructor

(1)函數(shù)原型

    constructor(props) {
        super(props);
        this.state = {}
    }

(2)基本介紹

  • 它是組件的構(gòu)造函數(shù)袖扛。它的第一個語句必須是 super(props),參數(shù)props值為外界傳入的屬性十籍,所以這里可以直接使用props值來初始化state蛆封。
  • 構(gòu)造函數(shù)將在組件被加載前最先調(diào)用,并且僅調(diào)用一次勾栗。

(3)常見用途
構(gòu)造函數(shù)最大的作用惨篱,就是在這里定義狀態(tài)機變量。

2. componentWillMount

(1)函數(shù)原型

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

(2)基本介紹

  • 在組件的生命周期中围俘,這個函數(shù)只會被執(zhí)行一次砸讳,從下個頁面返回到當前頁面也不會再調(diào)用。
  • 它在初始渲染(render 函數(shù)被 React Native 框架調(diào)用執(zhí)行)前被執(zhí)行界牡,當它執(zhí)行完后簿寂,render 函數(shù)會馬上被 React Native 框架調(diào)用執(zhí)行。
  • 如果子組件也有 componentWillMount 函數(shù)宿亡,它會在父組件的 componentWillMount 函數(shù)之后被調(diào)用常遂。

(3)常見用途
如果我們需要從本地存儲中讀取數(shù)據(jù)用于顯示,那么在這個函數(shù)里進行讀取是一個很好的時機挽荠。

注意:如果在這個函數(shù)里調(diào)用 setstate 函數(shù)改變了某些狀態(tài)機變量的值克胳, React Native 框架不會執(zhí)行渲染操作,而是等待這個函數(shù)執(zhí)行完成后再執(zhí)行初始渲染圈匆。

3. render

(1)函數(shù)原型

render() {
        return (
            <View style={styles.container}>
                <Text>{this.state.name}</Text>
            </View>
        )
    }

(2)基本介紹

  • render 是一個組件必須有的方法漠另,用于界面渲染。
  • 這個函數(shù)無參數(shù)跃赚,返回 JSX 或者其他組件來構(gòu)成 DOM笆搓。注意:只能返回一個頂級元素。
4. componentDidMount

(1)函數(shù)原型

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

(2)基本介紹

  • 在組件的生命周期中,這個函數(shù)只會被執(zhí)行一次砚作。
  • 它在初始渲染執(zhí)行完成后會馬上被調(diào)用窘奏。在組件生命周期的這個時間點之后嘹锁,開發(fā)者可以通過子組件的引用來訪問葫录、操作任何子組件。
  • 如果子組件也有 componentDidMount 函數(shù)领猾,它會在父組件的 componentDidMount 函數(shù)之前被調(diào)用米同。

(3)常見用途
如果 React Native 應(yīng)用需要在程序啟動并顯示初始界面后從網(wǎng)絡(luò)側(cè)獲取數(shù)據(jù),那么把從網(wǎng)絡(luò)側(cè)獲取數(shù)據(jù)的代碼放在這個函數(shù)里是一個不錯的選擇摔竿。

5. componentWillReceiveProps

(1)函數(shù)原型

componentWillReceiveProps(nextProps) {
        if (nextProps.name != this.state.name) {
            this.setState({
                name: nextProps.name
            })
        }
    }

(2)基本介紹

  • 組件的初始渲染執(zhí)行完成后面粮,當組件接收到新的 props 時,這個函數(shù)將被調(diào)用继低。
  • 這個函數(shù)不需要返回值熬苍。接收一個 object 參數(shù), object 里是新的 props袁翁。
  • 如果新的 props 會導致界面重新渲染柴底,這個函數(shù)將在渲染前被執(zhí)行。在這個函數(shù)中粱胜,老的 props 可以通過 this.props 訪問柄驻,新的 props 在傳入的 object 中。
  • 如果在這個函數(shù)中通過調(diào)用 this.setState 函數(shù)改變某些狀態(tài)機變量的值焙压, React Native 框架不會執(zhí)行對這些狀態(tài)機變量改變的渲染鸿脓,而是等 componentWillReceiveProps 函數(shù)執(zhí)行完成后一起渲染。

注意:當 React Native 初次被渲染時涯曲,componentWillReceiveProps 函數(shù)并不會被觸發(fā)野哭,這種機制是故意設(shè)計的。

6. shouldComponentUpdate

(1)函數(shù)原型

    shouldComponentUpdate(nextProps, nextState) {
        // nextProps 最新的屬性
        // nextState 將要渲染的狀態(tài)
        return true;
    }

(2)基本介紹

  • 組件的初始渲染執(zhí)行完成后幻件,當組件接收到新的 state 或者 props 時這個函數(shù)將被調(diào)用拨黔。
  • 該函數(shù)接收兩個 object參數(shù),其中第一個是新的 props傲武,第二個是新的 state蓉驹。
  • 該函數(shù)需要返回一個布爾值,告訴 React Native 框架針對這次改變揪利,是否需要重新渲染本組件态兴。默認返回true。如果此函數(shù)返回 false疟位,React Native 將不會重新渲染本組件瞻润,相應(yīng)的,該組件的 componentWillUpdatecomponentDidUpdate 函數(shù)也不會被調(diào)用。

(3)常見用途
這個函數(shù)常常用來阻止不必要的重新渲染绍撞,提高 React Native 應(yīng)用程序性能正勒。
比如我們可以在該函數(shù)中比較新老版本的 stateprops,判斷是否需要進行重新渲染傻铣。下面是一個簡單的使用樣例:

shouldComponentUpdate(nextProps, nextState) {
  if(this.state.inputedNum.length < 3) return false;
  return true;
}
7. componentWillUpdate

(1)函數(shù)原型

    componentWillUpdate(nextProps, nextState) {
        console.log('componentWillUpdate');
    }

(2)基本介紹

  • 組件的初始渲染執(zhí)行完成后章贞, React Native 框架在重新渲染該組件前會調(diào)用這個函數(shù)。
  • 該函數(shù)不需要返回值非洲,接收兩個 object 參數(shù)鸭限,其中第一個是新的 props,第二個是新的 state两踏。
  • 我們可以在這個函數(shù)中為即將發(fā)生的重新渲染做一些準備工作败京,但不能在這個函數(shù)中通過 this.setState 再次改變狀態(tài)機變量的值。如果需要改變梦染,則在 componentWillReceiveProps 函數(shù)中進行改變赡麦。
8. componentDidUpdate

(1)函數(shù)原型

componentDidUpdate(prevProps, prevState) {
        console.log('componentDidUpdate');
    }

(2)基本介紹

  • React Native 框架在重新渲染該組件完成后會調(diào)用這個函數(shù)(組件第一次渲染執(zhí)行完成后不調(diào)用該函數(shù))。
  • 該函數(shù)不需要返回值帕识,接收兩個 object 參數(shù)泛粹,其中第一個是渲染前的 props,第二個是渲染前的 state渡冻。
9. componentWillUnmount

(1)函數(shù)原型

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

(2)基本介紹

  • 在組件被卸載前戚扳,這個函數(shù)將被執(zhí)行。
  • 這個函數(shù)沒有參數(shù)族吻,也沒不需要返回值帽借。

(3)常見用途
如果組件申請了某些資源或者訂閱了某些消息,那么需要在這個函數(shù)中釋放資源超歌,取消訂閱砍艾。

三、舉例

1.示例代碼:

'use strict';

import React, { Component, PropTypes } from 'react';
import {
    View,
    Text,
    Button,
    StyleSheet,
    AppRegistry
} from 'react-native';

class LifecycleClass extends Component {

    // 聲明屬性類型
    static propTypes = {
        name: PropTypes.string,
    };

    // 聲明屬性默認值
    static defaultProps = {
        name: 'xiaowang'
    };

    constructor(props) {
        // 初始化(只調(diào)用一次)
        super(props);

        this.state = {
            name: props.name
        }
    }
    
    componentWillMount() {
        // 組件將要加載(只調(diào)用一次)
    }

    componentDidMount() {
        // 組件已經(jīng)加載(只調(diào)用一次)
    }

    componentWillReceiveProps(nextProps) {
        // 組件接收到外部屬性改變(屬性改變時調(diào)用巍举,可調(diào)用多次)
        if (nextProps.name != this.state.name) {
            this.setState({
                name: nextProps.name
            })
        }
    }

    shouldComponentUpdate(nextProps, nextState) {
        // 組件是否要刷新  nextProps: 最新的屬性    nextState: 將要渲染的狀態(tài)
        return true;
    }

    componentWillUpdate(nextProps, nextState) {
        // 組件將要刷新
    }

    componentDidUpdate(prevProps, prevState) {
        // 組件已經(jīng)刷新
    }

    componentWillUnmount() {
        // 組件將要卸載
    }

    render() {
        // 渲染組件
        return (
            <View style={styles.container}>
                <Text>{this.state.name}</Text>
            </View>
        )
    }
}

2.執(zhí)行結(jié)果:

// --------------初次渲染--------------
// 打印結(jié)果:
constructor
componentWillMount
render
componentDidMount


// --------------外部修改name屬性--------------
// 打印結(jié)果:
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate


// --------------關(guān)閉該組件--------------
componentWillUnmount

demo地址:RN組件生命周期demo

后記:本人工作中使用的就是RN脆荷,雖然已經(jīng)很熟練,但在工作中發(fā)現(xiàn)還有知識點遺漏懊悯,所以想寫一個系列文章蜓谋,把所有知識點再過一遍,以達到復習查缺補漏的效果炭分。文章中很多內(nèi)容都是借鑒別人的桃焕,但不是完全盲目照搬,取其精華去其糟粕捧毛,我把該有的知識點都帶上观堂,再加上自己的理解让网,目標就是將一個知識點講明白,理清楚师痕,并配上自己在實際使用過程中遇到的坑溃睹,幫助自己和大家日后參考。

注:如有雷同胰坟,純屬我抄的因篇!哈哈

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市腕铸,隨后出現(xiàn)的幾起案子惜犀,更是在濱河造成了極大的恐慌,老刑警劉巖狠裹,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異汽烦,居然都是意外死亡涛菠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門撇吞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俗冻,“玉大人,你說我怎么就攤上這事牍颈∑。” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵煮岁,是天一觀的道長讥蔽。 經(jīng)常有香客問我,道長画机,這世上最難降的妖魔是什么冶伞? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮步氏,結(jié)果婚禮上响禽,老公的妹妹穿的比我還像新娘。我一直安慰自己荚醒,他們只是感情好芋类,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著界阁,像睡著了一般侯繁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铺董,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天巫击,我揣著相機與錄音禀晓,去河邊找鬼。 笑死坝锰,一個胖子當著我的面吹牛粹懒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播顷级,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凫乖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弓颈?” 一聲冷哼從身側(cè)響起帽芽,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翔冀,沒想到半個月后导街,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡纤子,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年搬瑰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片控硼。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡泽论,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卡乾,到底是詐尸還是另有隱情翼悴,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布幔妨,位于F島的核電站鹦赎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏陶冷。R本人自食惡果不足惜钙姊,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望埂伦。 院中可真熱鬧煞额,春花似錦、人聲如沸沾谜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽基跑。三九已至婚温,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間媳否,已是汗流浹背栅螟。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工荆秦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人力图。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓步绸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吃媒。 傳聞我的和親對象是個殘疾皇子瓤介,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容