ReactNative中組件的生命週期

React-Native生命週期

開發中組件免不了要與用戶互動,React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然後用戶互動,導致狀態變化,從而觸發重新渲染 UI。下圖爲ReactNative中組件的生命週期,根據執行順序在對應的函數中做對應的操作

這裏寫圖片描述

這張經典的圖描述了ReactNative組件從創建運行銷燬的整個過程,其中經常用到的是創建過程,初始化的時候會調用5個函數,這5個函數在整個組件創建到銷燬的過程中只調用一次。

初始化過程

getDefaultProps (ES6廢除了這樣的寫法)

  • 該函數用於初始化一些默認的屬性,通常會將固定的內容放在這個函數 中進行初始化和賦值,一般放置一些常量
  • 在組件中,可以利用this.props獲取在這裏初始化它的屬性
  • 由於組件初始化後,再次使用該組件不會調用getDefaultProps函數,所以組件自己不可以自己修改props(即:props可認爲是隻讀的),只可由其他組件調用它時在外部修改。
  • 注意:如果父組件傳遞過來的Props和你在該函數中定義的Props的key一樣,將會被覆蓋

getInitalState(ES6廢除了這樣的寫法)

  • 該函數是用於對組件的一些狀態進行初始化,一般放置一些變量
  • 由於該函數不同於getDefaultProps,在以後的過程中,會再次調用
  • 所以可以將控制控件的狀態的一些變量放在這裏初始化,可以通過this.state來獲取值、修改state值, 比如:
this.setState({
    name:testName, 
});
  • 注意:
    • 一旦調用了this.setState方法,組件一定會調用render方法,對組件進行再次的渲染,不過,如果React框架會自動根據DOM的狀態來判斷是否需要真正的渲染。只有改變纔會重新渲染,這種狀態被稱爲狀態機
    • 爲了在使用中不出現空值,建議初始化state的時候儘可能給每一個可能用到的值都賦一個初始值。
    • -

componentWillMount

  • 在render前,getInitalState之後調用。僅調用一次,可以用於改變state操作
  • 相當於OC中的ViewWillAppear方法

render

  • 組件渲染函數,會返回一個Virtual DOM,只允許返回一個最外層容器組件。render函數儘量保持純淨,只渲染組件,不修改狀態,不執行副操作(比如計時器)
  • 在render函數中,只可通過this.state和this.props來訪問在之前函數中初始化的數據值

componentDidMount

  • 在調用了render方法後,React會根據Virtual DOM來生成真實DOM,生成完畢後會調用該函數。
  • 主要在該函數中執行網絡請求,定時器開啓等加載數據的操作
  • 因爲UI已經成功被渲染出來, 所以放在這個函數裏進行請求操作,不會出現UI上的錯誤。

運行過程

componentWillReceiveProps

  • props改變(父容器來更改或是redux),將會調用該函數。新的props將會作爲參數傳遞進來,老的props可以根據this.props來獲取。我們可以在該函數中對state作一些處理,其實就是指父元素對組件的props或state進行了修改
  • 注意:在該函數中更新state不會引起二次渲染。

shouldComponentUpdate

  • 該函數傳遞過來兩個參數,新的state和新的props。state和props的改變都會調到該函數。該函數主要對傳遞過來的nextProps和nextState作判斷。如果返回true則重新渲染,如果返回false則不重新渲染。在某些特定條件下,我們可以根據傳遞過來的props和state來選擇更新或者不更新,一般用於優化,提高效率。

componentWillUpdate

  • 組件刷新前調用,類似componentWillMount
  • 組件上會接收到新的props或者state渲染之前,調用該方法。但是不可以在該方法中更新state和props。

componentDidUpdate

  • 和初始化時期的componentDidMount類似,在render之後,真實DOM生成之後調用該函數。傳遞過來的是當前的props和state。在該函數中同樣可以使用this.getDOMNode()來拿到相應的DOM節點。如果你需要在運行中執行某些副操作,請在該函數中完成

銷燬過程

componentWillUnmount

  • 用於清理一些無用的內容。在這裏進行一些相關的銷燬操作,比如定時器,監聽等等

props和state

  • 關於Props(ES6的寫法)
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  Platform,
  StyleSheet,
  View,
  Text,
} from 'react-native';

class BClass extends Component<{}> {
    render() {
        console.log('title變化',this.props.title);
      return (
        <View>
              <Text>{this.props.title}</Text>
        </View>
      );
    }
}
BClass.propTypes = {
    title:PropTypes.String
};
BClass.defaultProps = {title:'xiaoming'};

export default class AClass extends Component<{}> {
  render() {
    return (
        <View style={styles.container}>
            {/* 顯示初始值 */}
            <BClass />
            {/* 變化值 */}
            <BClass title = 'xiaobai'/>
        </View>
    );
  }
}

定義了BClass且title的默認值爲xiaoming,然後通過它的父組件AClass給BClass中title賦值,然後打印log
log:
這裏寫圖片描述
可以看出原先的xiaoming被修改成了xiaobai

  • 關於State(ES6的寫法)
export default class AClass extends Component<{}> {

  constructor(props){
      super(props);
          this.state = {
            name : '000'
        };
        console.log('初始化' +'name:'+this.state.name + ' ' + 'age:'+this.state.age);
    }
   componentWillMount(){
         this.setState({
             name : 'AAA',
             age:16
        })
   }

  render() {
    console.log('改變前' +'name:'+this.state.name + ' ' + 'age:'+this.state.age);
    return (

        <View style={styles.container}>
            <Text>{this.state.name} </Text>
            <Text>{this.state.age} </Text>
        </View>
    );
  }


  componentDidMount(){
         this.setState({
             name : 'BBB',
             age:18
        })
        console.log('改變後' + 'name:'+this.state.name + ' ' + 'age:'+this.state.age);
   }
}

可以看到,初始化之後
初始化一個state爲name,然後在componentWillMount函數和componentDidMount函數中改變已經初始化的name和沒有聲明age,打印出來
log:
這裏寫圖片描述

當componentDidMount函數執行完之後依然會引發render再次渲染

  • 關於Prop和State的區別,

    • 相同點

      1.不管是props還是state的改變,都會引發render的重新渲染。

      2.都能由自身組件的相應初始化函數設定初始值。

    • 不同點

      1.初始值來源:state的初始值來自於自身的getInitalState(constructor)函數;props來自於父組件或者自身getDefaultProps(若key相同前者可覆蓋後者)。

      2.修改方式:state只能在自身組件中setState,不能由父組件修改;props只能由父組件修改,不能在自身組件修改。

      3.對子組件:props是一個父組件傳遞給子組件的數據流,這個數據流可以一直傳遞到子孫組件;state代表的是一個組件內部自身的狀態,只能在自身組件中存在。

盜用網上的一張圖:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章