【RN - 基礎】之React Native組件的生命周期


下圖描述了React Native中組件的生命周期:

 

從上圖中可以看到,React Native組件的生命周期可以分為初始化階段、存在階段和銷毀階段。

 

實例化階段

實例化階段是React Native組件生命周期的三個階段中最常用的階段,該階段是組件的構建、展示階段,該階段中的幾個方法的功能解析如下:

getDefaultProps:

該函數用於初始化一些默認的屬性。

在組件中可以利用 this.props.* 的方式獲取在這個函數中定義的屬性。

注意:this.props是只讀的區域,組件中不可以修改props中的屬性。

getInitialState:

該函數用於對組件的一些狀態進行初始化。

可以將控制組件狀態的一些變量在這里初始化(通過this.state來獲取值,通過this.setState來修改值)。

注意:一旦調用了this.setState方法,組件就一定會調用render函數對組件進行再次渲染,不過React框架會自動根據DOM的狀態來判斷是否需要真正的渲染。

render:

render函數返回JSX或其他組件來構成DOM(注意:只能返回一個頂級元素)。

在render函數中,只可以通過this.props和this.state來訪問在之前的函數中初始化的數據。

componentDidMount:

在調用了render函數,組件加載成功並被成功渲染出來以后,所要執行的后續操作(如網絡請求等加載數據的操作),一般會在這個函數中進行。因為UI已經被渲染出來了,所以放在這個函數中進行的請求操作,不會出現UI上的錯誤。

注意:如果想要在主類中書寫多個生命周期函數(getInitialState等),需要使用ES 5的語法,如果使用ES 6的語法會報錯。

 

存在階段和銷毀階段

當程序執行完了初始化階段最后調用的componentDidMount函數之后,程序就開始正常的運行起來,此時就進入了存在階段。

存在階段執行流程:

程序在運行過程中,如果對this.state或this.props進行了修改,那么就會觸發存在階段的多個函數(調用流程如上圖所示)。

無論是修改this.state還是this.props,系統都會調用shouldComponentUpdate函數,判斷視圖是否需要渲染,如果不需要,則忽略本次狀態修改,回到運行狀態;如果需要,則在通過componentWillUpdate函數准備之后,重新調用render函數進行渲染。

注意:this.state使用的是狀態機機制,即將組件看成一個狀態機,一開始有一個初始狀態,然后在用戶互動的時候改變組件狀態,從而觸發重新渲染UI。

銷毀階段執行流程:

執行銷毀階段的情況有多種,如:當系統遇到錯誤而崩潰時;系統空間不足時;APP被用戶推出時,等等等等。

當遇到上述問題時,系統就會進入銷毀階段,這個階段只有一個過程:componentWillUnmount,這個方法用來清空一些無用內容,如:點擊事件的Listener等。

注意:銷毀階段是程序執行的出口,只要執行了銷毀階段,就表示程序已經自然或不自然的退出了。

 

狀態機

上面說到,在React Native生命周期初始化階段的getInitialState方法中用到了狀態機的原理,狀態機原理即通過修改程序中狀態機中的屬性的值,來達到改變界面顯示的目的。狀態機的一段示例代碼如下:

var BTouchableDemo = React.createClass({
    getInitialState(){
        return {
            content: '觸摸事件響應器'
        }
    },
    render() {
        return (
            <View style={styles.containerStyle}>
                <TouchableOpacity
                    onPress={() => this.changeResultContent('點擊')}
                    onPressIn={() => this.changeResultContent('按下')}
                    onPressOut={() => this.changeResultContent('抬起')}
                    onLongPress={() => this.changeResultContent('長按')}>
                    <View style={styles.loginContainerStyle}>
                        <Text style={styles.loginTextStyle}>TouchableOpacity</Text>
                    </View>
                </TouchableOpacity>
                <Text style={styles.resultStyle}>{this.state.content}</Text>
            </View>
        );
    },
    changeResultContent(content) {
        this.setState({
            content: content
        });
    }
});

可以看到,上面一段代碼通過修改狀態機中的content屬性,來修改底部的Text中的文本信息。

注意:如果是要獲取狀態機中的屬性值,則可以直接通過 this.state.* 的方式獲取;如果想要設置(更新)狀態機中某個屬性的值,則必須要通過 this.setState 方法設置。

 

ES 5和ES 6代碼的比較

ES 6的代碼風格相對於ES 5有很大的改變,實例化階段的幾個方法(render、getDefaultProps和getInitialState)在ES 5和ES 6的代碼差別很大。

使用ES 5的代碼編寫:

var CLifeCycle = React.createClass({
    // 設置一些常量(程序中不可改變的量)
    getDefaultProps(){
        return {name: 'Jack'};
    },
    // 設置狀態機屬性(程序中可以改變的量)
    getInitialState(){
        return {age: 20};
    },
    // 渲染布局
    render(){
        return (
            <View style={styles.containerStyle}>
                <Text style={styles.textStyle}>我是ES 5語法模板</Text>
            </View>
        );
    }
});

 

使用ES 6的代碼編寫:

export default class CLifeCycle extends Component {
    // 設置狀態機屬性(程序中可以改變的量)
    constructor(props) {
        super(props);
        this.state = {age: 20};
    }

    // 渲染布局
    render() {
        return (
            <View style={styles.containerStyle}>
                <Text style={styles.textStyle}>我是ES 6語法模板</Text>
            </View>
        );
    }
}
// 設置一些常量(程序中不可改變的量)的數據類型
CLifeCycle.propTypes = {name: React.PropTypes.string};
// 設置一些常量(程序中不可改變的量)的默認值
CLifeCycle.defaultProps = {name: 'Jack'};

 

獲取真實DOM節點

在React Native中,組件並不是真正的DOM節點,而是存在於內存中的一種數據結構,叫做虛擬DOM。只有當它插入文檔之后,才會稱為真正的DOM。

如果想要通過組件獲取真正的DOM節點,可以使用  ref  屬性設置標記,然后在需要使用的地方通過  this.refs.*  訪問這個組件。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM