React-Native 之 生命週期

前言

  • 學習本系列內容須要具有必定 HTML 開發基礎,沒有基礎的朋友能夠先轉至 HTML快速入門(一) 學習react

  • 本人接觸 React Native 時間並非特別長,因此對其中的內容和性質瞭解可能會有所誤差,在學習中若是有錯會及時修改內容,也歡迎萬能的朋友們批評指出,謝謝算法

  • 文章初版出自簡書,若是出現圖片或頁面顯示問題,煩請轉至 簡書 查看 也但願喜歡的朋友能夠點贊,謝謝react-native

React Native 組件執行順序介紹


  • 全部的程序都有生命週期,這是開發人員關注的點,好比iOS中有一個 ViewDidLoad 來初始化,在React Native中又是在哪裏?這邊從文檔中截取的一張圖並註釋了下,很好地描述了React Native組件的執行順序

React Native執行順序.png

  • 從圖中能夠看出,在React Native中,組件的生命週期大體能夠分爲3個階段(實例化階段、存在階段、銷燬階段),其中最常接觸的爲實例化階段,這個階段負責組件的構建和展現的時間,須要咱們根據幾個函數的調用過程,控制好組件的展現和邏輯處理

實例化階段函數功能分析


  • getDefaultProps:該函數用於初始化一些默認屬性,一般會將固定的內容放在這個函數中進行初始化和賦值網絡

    • 在組件中,咱們能夠利用 this.props 獲取在這裏初始化它的屬性,因爲組件初始化後,再辭使用該組件不會調用 getDefaultProps 函數,因此組件本身不能夠修改props,只可由其餘組件調用它時再外部進行修改
  • getInitialState:該函數用於對組件一些狀態進行初始化數據結構

    • 該函數不一樣於getDefaultProps,在之後的過程當中,會再次調用,因此能夠將控制控件狀態的一些變量放在這裏初始化,好比控件上顯示的文字,能夠經過this.state來獲取值,經過 this.setState 來修改state值


    var SMZQ = React.createClass({
    
    		// 用於設置一些值固定不變或上下界面值傳遞
    		getDefaultProps(){
    			return{
        			number1: 1,
        			number2: 2
    			}
    		},
    
    		// 用於設置一些可變或者用來刷新界面
    		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>計算和</Text>
            			</TouchableOpacity>
            			<TouchableOpacity
                			onPress={() => {this.setState({sum: this.state.sum + 1})}}
            			>
                			<Text>和的基礎上+1</Text>
            			</TouchableOpacity>
        			</View>
    			);
    		}
    	});

    效果:
    getDefaultProps和getInitialState使用.gif框架

    • 注:一旦調用了 this.setState方法,組件必定會調用render方法,對組件進行再次渲染,不過,React框架會根據DOM的狀態自動判斷是否須要真正渲染
  • componentWillMount:至關於OC中的 ViewWillAppear 方法,在組件簡要被加載到視圖以前調用,沒有太多的功能異步

  • render:它是每一個組件必需具有的方法,本質上是個函數,而且返回JSX或者其餘組件來構成DOM,和Android的XML佈局相似函數

    • 在該函數中,只能經過this.state和this.props來訪問以前在函數中初始化的數值
    • 注:只能返回一個頂級元素
  • componentDidMount:在調用了render方法,組件加載成功並被成功渲染出來以後,所要執行的後續操做,通常都會在這個函數中進行,好比常常要面對的網絡請求等加載數據操做佈局

    • 由於UI已經成功渲染,並且這裏面是異步的,索引放在這個函數進行數據的請求等複雜的操做,不會出現UI錯誤

存在階段函數功能分析


  • componentWillReceiveProps:指父元素對組件的props或state進行了修改
  • shouldComponentUpadate:通常用於優化,能夠返回false或true來控制是否進行渲染
  • componentWillUpdate:組件刷新前調用,相似componentWillMount
  • componentDidUpdate:更新後的hook

銷燬階段函數功能分析


  • 用於清理一些無用的內容,如:點擊事件Listener,只有一個過程:componentWillUnmount

經常使用知識點分析


  • this.state:開發中,組件確定要與用戶互動,React的一大創新就是將組件當作一個狀態機,一開始有一個初始狀態,而後用戶互動,致使狀態變化,從而觸發從新渲染UI,舉個例子性能

    var SMZQ = React.createClass({
    
    		// 用於設置一些可變或者用來刷新界面
    		getInitialState(){
    			return{
        			isPositive: true,
        			content:'5是否是負數'
    			}
    		},
    
    		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 = '值不是負數';
        		}else {
            		isPositive = true;
            		content = '值是負數';
        		}
        		this.setState({
            		isPositive: isPositive,
            		content: content
        		});
    		}
    	});

    效果:
    this.state探究.gif

    • 當用戶點擊組件,致使狀態變化,this.setState方法就修改狀態值,每次修改之後,會自動調用this.render方法,再次渲染組件
    • 能夠把組件當作一個狀態機,根據不一樣的status有不一樣的UI展現,只要使用setState改變狀態值,根據diff算法算出有差值後,就會執行ReactDom的render方法,從新渲染頁面
    • 注:因爲this.props和this.state都用於描述組件的特性,可能會產生混淆,一個簡單的區分方法就是 —— this.props表示那些一旦定義,就再也不更改的特性,而this.state是會隨着用戶互動而產生改變的特性
  • 獲取真實的DOM節點

    • 在React Native中,組件並非真實的DOM節點,而是存在於內存中的一種數據結構 ,叫虛擬DOM
    • 只有當它插入文檔後,纔會變成真實的DOM
    • 根據React的設計,全部DOM變更,都先在虛擬DOM上發生,而後再將實際發生變更的部分,反應在真實DOM上,這種算法叫作DOM diff,它能夠極大提升網頁的性能表現
    • 有時須要從組件獲取真實DOM節點,這時就須要用到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 () {
        		// 讓輸入框得到焦點
        		this.refs.mytextInput.focus();
        		// 查看內容屬性
        		console.log(this.refs.mainView);
    		}
    	});

    效果:
    打印結果.png

    • 能夠看出,組件View的子節點有一個文本輸入框,用於獲取用戶的輸入,這時就必須獲取真實的DOM節點,虛擬DOM是拿不到用戶輸入的,爲了作到這一點,文本輸入框必須有一個ref屬性,而後this.refs.refName就會返回這個真實的DOM節點
    • 須要注意的是,因爲this.refs.refName屬性獲取的是真實DOM,全部必須等到虛擬DOM插入文檔後,才能使用這個屬性,不然會報錯。上面代碼中,經過組件指定Click事件的回調函數,確保只有等到真實DOM發生Click事件以後,纔會讀取this.refs.refName屬性

補充


  • 什麼是DOM Diff算法(下面內容是搜索的內容)
    • Web界面由DOM樹來構成,當其中某一部分發生變化時,其實就是對應的某個DOM節點發生了變化。在React中,構建UI界面的思路是由當前狀態決定界面。先後兩個狀態就對應兩套界面,而後由React來比較兩個界面的區別,這就須要對DOM樹進行Diff算法分析
    • 即給定任意兩棵樹,找到最少的轉換步驟。可是標準的的Diff算法複雜度須要O(n^3),這顯然沒法知足性能要求。要達到每次界面均可以總體刷新界面的目的,勢必須要對算法進行優化。這看上去很是有難度,然而Facebook工程師卻作到了,他們結合Web界面的特色作出了兩個簡單的假設,使得Diff算法複雜度直接下降到O(n)
      • 兩個相同組件產生相似的DOM結構,不一樣的組件產生不一樣的DOM結構
      • 對於同一層次的一組子節點,它們能夠經過惟一的id進行區分 -算法上的優化是React整個界面Render的基礎,事實也證實這兩個假設是合理而精確的,保證了總體界面構建的性能
相關文章
相關標籤/搜索