关闭

Android React Native组件的生命周期

标签: AndroidReactFacebook组件生命周期
4384人阅读 评论(2) 收藏 举报
分类:

和Android一样,React的组件也有对应的生命周期。Android React Native组件的生命周期可以总的概括为下面这一张图。

这里写图片描述

可以把组件生命周期大致分为三个阶段:

  • 第一阶段:是组件第一次绘制阶段,如图中的上面虚线框内,在这里完成了组件的加载和初始化;
  • 第二阶段:是组件在运行和交互阶段,如图中左下角虚线框,这个阶段组件可以处理用户交互,或者接收事件更新界面;
  • 第三阶段:是组件卸载消亡的阶段,如图中右下角的虚线框中,这里做一些组件的清理工作。

生命周期回调函数总共有10个。

  • object getDefaultProps()
    在组件类创建的时候调用一次,然后返回值被缓存下来。全局调用一次,所有实例共享。

  • object getInitialState()
    在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。

  • componentWillMount ()
    在初始化渲染执行之前立刻调用

  • ReactComponent render()
    这个方法是必须的,对视图进行渲染,你也可以返回 null 或者 false 来表明不需要渲染任何东西

  • componentDidMount()
    在初始化渲染执行之后立刻调用一次

  • componentWillReceiveProps(object nextProps)
    在组件接收到新的 props 的时候调用,也就是父组件修改子组件的属性时触发。在初始化渲染的时候,该方法不会调用。可以用于更新 state 来响应某个 prop 的改变。

  • boolean shouldComponentUpdate(object nextProps, object nextState)
    在接收到新的 props 或者 state,将要渲染之前调用,如果确定新的 props 和 state 不会导致组件更新,则此处应该 返回 false。返回true将进行渲染。

  • componentWillUpdate(object nextProps, object nextState)
    在接收到新的 props 或者 state 并且shouldComponentUpdate返回true时调用

  • componentDidUpdate(object prevProps, object prevState)
    在组件的更新已经同步到 DOM 中之后立刻被调用

  • componentWillUnmount()
    在组件从 DOM 中移除的时候立刻被调用。在该方法中执行任何必要的清理,比如无效的定时器,或者清除在 componentDidMount 中创建的 DOM 元素。

下面贴出测试代码。

/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';

var React = require('react-native');
var {
    AppRegistry,
    StyleSheet,
    View,
    Text
} = React;


var AwesomeProject = React.createClass({
    //在组件类创建的时候调用一次,然后返回值被缓存下来。
    getDefaultProps:function(){
        console.log("getDefaultProps");
        return null;
    },
    //初始化状态,在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。
    getInitialState:function(){
        console.log("getInitialState");
        return null;
        //必须有返回值,可以是NULL或者一个对象。
    },
    //组件将要被渲染
    componentWillMount:function(){
        console.log("componentWillmount");

    },
    //渲染视图
    render:function(){
        console.log("render");

        return (
            <View>

            </View>
        );
        //你也可以返回 null 或者 false 来表明不需要渲染任何东西
    },
    //渲染视图完成后
    componentDidMount:function(){
        console.log("componentDidMount");

        this.loadDataToSetState();
    },
    //组件接收到新属性,在初始化渲染的时候,该方法不会调用。
    componentWillReceiveProps:function(nextProps){
        console.log("componentWillReceiveProps");
        //console.log(nextProps);
    },
    //组件是否需要更新
    shouldComponentUpdate:function(nextProps,nextState){
        console.log("shouldComponentUpdate");
        //console.log(nextProps+"|"+nextState);
        return true;
    },
    //组件将要被更新
    componentWillUpdate:function(nextProps,nextState){
        console.log("componentWillUpdate");
        //console.log(nextProps+"|"+nextState);
    },
    //组件更新完毕
    componentDidUpdate:function(prevProps,prevState){
        console.log("conponentDidUpdate");
        //console.log(prevProps+"|"+prevState);
    },

    //组件被销毁之前,做清理操作
    componentWillUnmount:function(){
        console.log("componentWillUnmount");
    },

    loadDataToSetState:function(){
        console.log("loadDataToSetState");
        this.setState({
            name : "RN"
        }) 
    },


});

var styles = StyleSheet.create({

});


AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

最后的输出如下,我们在componentDidMount中调用了loadDataToSetState函数,该函数中通过了setState函数对state进行了设置,这时候就会回调shouldComponentUpdate,如果返回true,则会继续调用componentWillUpdaterender,conponentDidUpdate,之后按返回键退出应用,则会进行销毁操作,回调componentWillUnmount

getDefaultProps
getInitialState
componentWillmount
render
componentDidMount
loadDataToSetState
shouldComponentUpdate
componentWillUpdate
render
conponentDidUpdate
componentWillUnmount

而关于componentWillReceiveProps函数的触发是在props属性改变之后才会触发,这个比较复杂,什么情况下会改变呢,也就是父组件改变子组件的属性的时候。

首先我们定义一个子组件

var Name =React.createClass({
    getDefaultProps:function(){
        console.log("Name getDefaultProps");
        return null;
    },
    getInitialState:function(){
        console.log("Name getInitialState");
        return null;
    },
    componentWillMount:function(){
        console.log("Name componentWillmount");
    },
    render:function(){
        console.log("Name render");
        return (
            <Text>
                Hello,{this.props.name? this.props.name:"None!"}
            </Text>
        );
    },
    componentDidMount:function(){
        console.log("Name componentDidMount");
    },
    componentWillReceiveProps:function(nextProps){
        console.log("Name componentWillReceiveProps");
        console.log(nextProps);
    },
    shouldComponentUpdate:function(nextProps,nextState){
        console.log("Name shouldComponentUpdate");
        return true;
    },
    componentWillUpdate:function(nextProps,nextState){
        console.log("Name componentWillUpdate");
    },
    componentDidUpdate:function(prevProps,prevState){
        console.log("Name conponentDidUpdate");
    },
    componentWillUnmount:function(){
        console.log("Name componentWillUnmount");
    },
});

再定义一个父组件,在父组件的渲染函数中使用子组件,并为子组件设置name属性,即

<Name name={this.state.name}></Name>

而在父组件中,getInitialState函数中返回父组件的state值

return {name:"a"};

当组件加载完毕后,通过setState函数设置父组件的state

this.setState({
            name:"lizhangqu"
        });

这时候会触发父组件的render函数重新渲染,而render函数中会对子组件的name重新赋值,也就是setState中的值。

父组件的代码如下。

var Parent = React.createClass({

    render:function(){
        return (
            <View>
                <Name name={this.state.name}></Name>
            </View>

        );
    },

    getInitialState:function(){

        return {name:"a"};
    },

    componentDidMount:function(){

        this.setState({
            name:"lizhangqu"
        });
    },
});

在界面中,我们直接使用父组件作为返回。

var AwesomeProject = React.createClass({
  render: function() {
    return (
        <Parent></Parent>
    );
  }
});

这时候,由于子组件的属性发生了变换,就会回调componentWillReceiveProps生命周期函数,整个生命周期函数如下(我们在componentWillReceiveProps函数中打印了该属性所在的对象),

Name getDefaultProps
Name getInitialState
Name componentWillmount
Name render
Name componentDidMount
Name componentWillReceiveProps
Object {name: "lizhangqu"}
Name shouldComponentUpdate
Name componentWillUpdate
Name render
Name conponentDidUpdate
Name componentWillUnmount

而关于调试,React-Native官网提供了一个Chrome下调试的插件,见Chrome Developer Tools ,安装了该插件后,在手机上的开发者选项中开启debug js,就可以在chrome中看到控制台输出的信息以及js的报错信息了。

4
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:972926次
    • 积分:10488
    • 等级:
    • 排名:第1629名
    • 原创:164篇
    • 转载:5篇
    • 译文:0篇
    • 评论:715条
    博客专栏
    我的微博
    最新评论