React-Native 之 生命周期

前言

  • 學(xué)習(xí)本系列內(nèi)容需要具備一定 HTML 開發(fā)基礎(chǔ)恕酸,沒有基礎(chǔ)的朋友可以先轉(zhuǎn)至 HTML快速入門(一) 學(xué)習(xí)

  • 本人接觸 React Native 時(shí)間并不是特別長拟杉,所以對(duì)其中的內(nèi)容和性質(zhì)了解可能會(huì)有所偏差厚脉,在學(xué)習(xí)中如果有錯(cuò)會(huì)及時(shí)修改內(nèi)容迟杂,也歡迎萬能的朋友們批評(píng)指出删铃,謝謝

  • 文章第一版出自簡書概荷,如果出現(xiàn)圖片或頁面顯示問題螺戳,煩請(qǐng)轉(zhuǎn)至 簡書 查看 也希望喜歡的朋友可以點(diǎn)贊搁宾,謝謝

React Native 組件執(zhí)行順序介紹


  • 所有的程序都有生命周期,這是開發(fā)人員關(guān)注的點(diǎn)倔幼,比如iOS中有一個(gè) ViewDidLoad 來初始化盖腿,在React Native中又是在哪里?這邊從文檔中截取的一張圖并注釋了下损同,很好地描述了React Native組件的執(zhí)行順序
React Native執(zhí)行順序.png
  • 從圖中可以看出翩腐,在React Native中,組件的生命周期大致可以分為3個(gè)階段(實(shí)例化階段膏燃、存在階段茂卦、銷毀階段),其中最常接觸的為實(shí)例化階段组哩,這個(gè)階段負(fù)責(zé)組件的構(gòu)建和展示的時(shí)間等龙,需要我們根據(jù)幾個(gè)函數(shù)的調(diào)用過程,控制好組件的展示和邏輯處理

實(shí)例化階段函數(shù)功能分析


  • getDefaultProps:該函數(shù)用于初始化一些默認(rèn)屬性禁炒,通常會(huì)將固定的內(nèi)容放在這個(gè)函數(shù)中進(jìn)行初始化和賦值

    • 在組件中而咆,我們可以利用 this.props 獲取在這里初始化它的屬性,由于組件初始化后幕袱,再辭使用該組件不會(huì)調(diào)用 getDefaultProps 函數(shù),所以組件自己不可以修改props暴备,只可由其他組件調(diào)用它時(shí)再外部進(jìn)行修改
  • getInitialState:該函數(shù)用于對(duì)組件一些狀態(tài)進(jìn)行初始化

    • 該函數(shù)不同于getDefaultProps,在以后的過程中们豌,會(huì)再次調(diào)用涯捻,所以可以將控制控件狀態(tài)的一些變量放在這里初始化浅妆,比如控件上顯示的文字,可以通過this.state來獲取值障癌,通過 this.setState 來修改state值


        var SMZQ = React.createClass({
    
            // 用于設(shè)置一些值固定不變或上下界面值傳遞
            getDefaultProps(){
                return{
                    number1: 1,
                    number2: 2
                }
            },
    
            // 用于設(shè)置一些可變或者用來刷新界面
            getInitialState(){
                return{
                    sum:0
                }
            },
    
            render() {
                return (
                    <View style={styles.container}>
                        <Text>number1:{this.props.number1}</Text>
                        <Text>number2:{this.props.number2}</Text>
                        <Text>sum:{this.state.sum}</Text>
                        <TouchableOpacity
                            onPress={() => {this.setState({sum: this.props.number1 + this.props.number2})}}
                        >
                            <Text>計(jì)算和</Text>
                        </TouchableOpacity>
                        <TouchableOpacity
                            onPress={() => {this.setState({sum: this.state.sum + 1})}}
                        >
                            <Text>和的基礎(chǔ)上+1</Text>
                        </TouchableOpacity>
                    </View>
                );
            }
        });
    
    

    效果:


    getDefaultProps和getInitialState使用.gif
    • 注:一旦調(diào)用了 this.setState方法凌外,組件一定會(huì)調(diào)用render方法,對(duì)組件進(jìn)行再次渲染涛浙,不過康辑,React框架會(huì)根據(jù)DOM的狀態(tài)自動(dòng)判斷是否需要真正渲染
  • componentWillMount:相當(dāng)于OC中的 ViewWillAppear 方法,在組件簡要被加載到視圖之前調(diào)用,沒有太多的功能

  • render:它是每個(gè)組件必需具備的方法轿亮,本質(zhì)上是個(gè)函數(shù)疮薇,并且返回JSX或者其他組件來構(gòu)成DOM,和Android的XML布局類似

    • 在該函數(shù)中我注,只能通過this.state和this.props來訪問之前在函數(shù)中初始化的數(shù)值
    • 注:只能返回一個(gè)頂級(jí)元素
  • componentDidMount:在調(diào)用了render方法按咒,組件加載成功并被成功渲染出來之后,所要執(zhí)行的后續(xù)操作但骨,一般都會(huì)在這個(gè)函數(shù)中進(jìn)行励七,比如經(jīng)常要面對(duì)的網(wǎng)絡(luò)請(qǐng)求等加載數(shù)據(jù)操作

    • 因?yàn)閁I已經(jīng)成功渲染,而且這里面是異步的奔缠,索引放在這個(gè)函數(shù)進(jìn)行數(shù)據(jù)的請(qǐng)求等復(fù)雜的操作掠抬,不會(huì)出現(xiàn)UI錯(cuò)誤

存在階段函數(shù)功能分析


  • componentWillReceiveProps:指父元素對(duì)組件的props或state進(jìn)行了修改
  • shouldComponentUpadate:一般用于優(yōu)化,可以返回false或true來控制是否進(jìn)行渲染
  • componentWillUpdate:組件刷新前調(diào)用添坊,類似componentWillMount
  • componentDidUpdate:更新后的hook

銷毀階段函數(shù)功能分析


  • 用于清理一些無用的內(nèi)容剿另,如:點(diǎn)擊事件Listener,只有一個(gè)過程:componentWillUnmount

常用知識(shí)點(diǎn)分析


  • this.state:開發(fā)中,組件肯定要與用戶互動(dòng)贬蛙,React的一大創(chuàng)新就是將組件看成一個(gè)狀態(tài)機(jī)雨女,一開始有一個(gè)初始狀態(tài),然后用戶互動(dòng)阳准,導(dǎo)致狀態(tài)變化氛堕,從而觸發(fā)重新渲染UI,舉個(gè)例子

        var SMZQ = React.createClass({
    
            // 用于設(shè)置一些可變或者用來刷新界面
            getInitialState(){
                return{
                    isPositive: true,
                    content:'5是不是負(fù)數(shù)'
                }
            },
    
            render() {
                return (
                    <View style={styles.container}>
                        <TouchableOpacity
                                onPress={() => {this.dealWithState(this.state.isPositive, 5)}}
                        >
                            <Text>{this.state.content}</Text>
                        </TouchableOpacity>
                    </View>
                );
            },
    
            dealWithState: function (data:Boolean, num:int) {
                var isPositive, content;
    
                if (num > 0){
                    isPositive = false;
                    content = '值不是負(fù)數(shù)';
                }else {
                    isPositive = true;
                    content = '值是負(fù)數(shù)';
                }
                this.setState({
                    isPositive: isPositive,
                    content: content
                });
            }
        });
                
    

    效果:


    this.state探究.gif
    • 當(dāng)用戶點(diǎn)擊組件野蝇,導(dǎo)致狀態(tài)變化讼稚,this.setState方法就修改狀態(tài)值,每次修改以后绕沈,會(huì)自動(dòng)調(diào)用this.render方法锐想,再次渲染組件
    • 可以把組件看成一個(gè)狀態(tài)機(jī),根據(jù)不同的status有不同的UI展示乍狐,只要使用setState改變狀態(tài)值赠摇,根據(jù)diff算法算出有差值后,就會(huì)執(zhí)行ReactDom的render方法,重新渲染頁面
    • 注:由于this.props和this.state都用于描述組件的特性藕帜,可能會(huì)產(chǎn)生混淆烫罩,一個(gè)簡單的區(qū)分方法就是 —— this.props表示那些一旦定義,就不再更改的特性洽故,而this.state是會(huì)隨著用戶互動(dòng)而產(chǎn)生改變的特性
  • 獲取真實(shí)的DOM節(jié)點(diǎn)

    • 在React Native中贝攒,組件并不是真實(shí)的DOM節(jié)點(diǎn),而是存在于內(nèi)存中的一種數(shù)據(jù)結(jié)構(gòu) 时甚,叫虛擬DOM
    • 只有當(dāng)它插入文檔后隘弊,才會(huì)變成真實(shí)的DOM
    • 根據(jù)React的設(shè)計(jì),所有DOM變動(dòng)撞秋,都先在虛擬DOM上發(fā)生长捧,然后再將實(shí)際發(fā)生變動(dòng)的部分,反應(yīng)在真實(shí)DOM上吻贿,這種算法叫做DOM diff,它可以極大提高網(wǎng)頁的性能表現(xiàn)
    • 有時(shí)需要從組件獲取真實(shí)DOM節(jié)點(diǎn),這時(shí)就需要用到ref屬性哑子,可以看下面的示例加深理解


        var SMZQ = React.createClass({
            render() {
                return (
                    <View ref="mainView" style={styles.container}>
                        <TouchableOpacity
                            onPress={() => {this.dealWithState()}}
                        >
                            <Text>值</Text>
                        </TouchableOpacity>
                        <TextInput ref="mytextInput"></TextInput>
                    </View>
                );
            },
    
            dealWithState: function () {
                // 讓輸入框獲得焦點(diǎn)
                this.refs.mytextInput.focus();
                // 查看內(nèi)容屬性
                console.log(this.refs.mainView);
            }
        });
    
    

    效果:


    打印結(jié)果.png
    • 可以看出舅列,組件View的子節(jié)點(diǎn)有一個(gè)文本輸入框,用于獲取用戶的輸入卧蜓,這時(shí)就必須獲取真實(shí)的DOM節(jié)點(diǎn)帐要,虛擬DOM是拿不到用戶輸入的,為了做到這一點(diǎn)弥奸,文本輸入框必須有一個(gè)ref屬性榨惠,然后this.refs.refName就會(huì)返回這個(gè)真實(shí)的DOM節(jié)點(diǎn)
    • 需要注意的是,由于this.refs.refName屬性獲取的是真實(shí)DOM盛霎,所有必須等到虛擬DOM插入文檔后赠橙,才能使用這個(gè)屬性,否則會(huì)報(bào)錯(cuò)愤炸。上面代碼中期揪,通過組件指定Click事件的回調(diào)函數(shù),確保只有等到真實(shí)DOM發(fā)生Click事件之后规个,才會(huì)讀取this.refs.refName屬性

補(bǔ)充


  • 什么是DOM Diff算法(下面內(nèi)容是搜索的內(nèi)容)
    • Web界面由DOM樹來構(gòu)成凤薛,當(dāng)其中某一部分發(fā)生變化時(shí),其實(shí)就是對(duì)應(yīng)的某個(gè)DOM節(jié)點(diǎn)發(fā)生了變化诞仓。在React中缤苫,構(gòu)建UI界面的思路是由當(dāng)前狀態(tài)決定界面。前后兩個(gè)狀態(tài)就對(duì)應(yīng)兩套界面墅拭,然后由React來比較兩個(gè)界面的區(qū)別活玲,這就需要對(duì)DOM樹進(jìn)行Diff算法分析
    • 即給定任意兩棵樹,找到最少的轉(zhuǎn)換步驟。但是標(biāo)準(zhǔn)的的Diff算法復(fù)雜度需要O(n^3)翼虫,這顯然無法滿足性能要求屑柔。要達(dá)到每次界面都可以整體刷新界面的目的,勢必需要對(duì)算法進(jìn)行優(yōu)化珍剑。這看上去非常有難度掸宛,然而Facebook工程師卻做到了,他們結(jié)合Web界面的特點(diǎn)做出了兩個(gè)簡單的假設(shè)招拙,使得Diff算法復(fù)雜度直接降低到O(n)
      • 兩個(gè)相同組件產(chǎn)生類似的DOM結(jié)構(gòu)唧瘾,不同的組件產(chǎn)生不同的DOM結(jié)構(gòu)
      • 對(duì)于同一層次的一組子節(jié)點(diǎn),它們可以通過唯一的id進(jìn)行區(qū)分
        -算法上的優(yōu)化是React整個(gè)界面Render的基礎(chǔ)别凤,事實(shí)也證明這兩個(gè)假設(shè)是合理而精確的饰序,保證了整體界面構(gòu)建的性能
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市规哪,隨后出現(xiàn)的幾起案子求豫,更是在濱河造成了極大的恐慌,老刑警劉巖诉稍,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝠嘉,死亡現(xiàn)場離奇詭異,居然都是意外死亡杯巨,警方通過查閱死者的電腦和手機(jī)蚤告,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來服爷,“玉大人杜恰,你說我怎么就攤上這事∪栽矗” “怎么了心褐?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長镜会。 經(jīng)常有香客問我檬寂,道長,這世上最難降的妖魔是什么戳表? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任桶至,我火速辦了婚禮,結(jié)果婚禮上匾旭,老公的妹妹穿的比我還像新娘镣屹。我一直安慰自己,他們只是感情好价涝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布女蜈。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伪窖。 梳的紋絲不亂的頭發(fā)上逸寓,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音覆山,去河邊找鬼竹伸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛簇宽,可吹牛的內(nèi)容都是我干的勋篓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼魏割,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼譬嚣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钞它,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤拜银,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后遭垛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盐股,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年耻卡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牲尺。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卵酪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谤碳,到底是詐尸還是另有隱情溃卡,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布蜒简,位于F島的核電站瘸羡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏搓茬。R本人自食惡果不足惜犹赖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望卷仑。 院中可真熱鬧峻村,春花似錦、人聲如沸锡凝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至张肾,卻和暖如春芭析,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吞瞪。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工馁启, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尸饺。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓进统,卻偏偏與公主長得像,于是被迫代替她去往敵國和親浪听。 傳聞我的和親對(duì)象是個(gè)殘疾皇子螟碎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • 一、看圖分析 在下圖中描述了React Native中組件的生命周期迹栓,我們可以根據(jù)其中的執(zhí)行順序在對(duì)應(yīng)的函數(shù)中做對(duì)...
    厲害了我的國閱讀 658評(píng)論 0 0
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南掉分,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個(gè)人覺得該教程講解深入淺出克伊,比目前大...
    leonaxiong閱讀 2,834評(píng)論 1 18
  • 在React Native中使用組件來封裝界面模塊時(shí)酥郭,整個(gè)界面就是一個(gè)大的組件,開發(fā)過程就是不斷優(yōu)化和拆分界面組件...
    朱_源浩閱讀 8,952評(píng)論 6 38
  • 曾經(jīng)的我,一次次的痛苦的問:為什么他會(huì)那樣對(duì)我犁跪,為什么他就不能那樣對(duì)我椿息。為什么他是這個(gè)樣子,他為什么不改變坷衍?...
    侯君_6ef0閱讀 272評(píng)論 0 4
  • 切勿做一個(gè)令人討厭的人 做事先做人 價(jià)值觀這種事寝优,真的很重要 你不清楚的東西不要自以為是,就算別人真的沒你懂的多枫耳,...
    復(fù)蘇森林閱讀 150評(píng)論 0 1