+生命周期 native react

2018-06-08 16:48:20 YU_M_K 阅读数 928

概述

就像 Android 开发中的 View 一样,React Native(RN) 中的组件也有生命周期(Lifecycle)。所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命周期,是合理开发的关键。RN 组件的生命周期整理如下图:

React Native 中组件的生命周期

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

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

生命周期回调函数

下面来详细介绍生命周期中的各回调函数。

getDefaultProps

在组件创建之前,会先调用getDefaultProps(),这是全局调用一次,严格地来说,这不是组件的生命周期的一部分。在组件被创建并加载候,首先调用getInitialState(),来初始化组件的状态。

componentWillMount

然后,准备加载组件,会调用componentWillMount(),其原型如下:

void componentWillMount()

这个函数调用时机是在组件创建,并初始化了状态之后,在第一次绘制render()之前。可以在这里做一些业务初始化操作,也可以设置组件状态。这个函数在整个生命周期中只被调用一次。

componentDidMount

在组件第一次绘制之后,会调用componentDidMount(),通知组件已经加载完成。函数原型如下:

void componentDidMount()

这个函数调用的时候,其虚拟 DOM 已经构建完成,你可以在这个函数开始获取其中的元素或者子组件了。需要注意的是,RN 框架是先调用子组件的componentDidMount(),然后调用父组件的函数。从这个函数开始,就可以和 JS 其他框架交互了,例如设置计时setTimeout或者setInterval,或者发起网络请求。这个函数也是只被调用一次。这个函数之后,就进入了稳定运行状态,等待事件触发。

componentWillReceiveProps

如果组件收到新的属性(props),就会调用componentWillReceiveProps(),其原型如下:

void componentWillReceiveProps(  
  object nextProps
)

输入参数nextProps是即将被设置的属性,旧的属性还是可以通过this.props来获取。在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态,这里调用更新状态是安全的,并不会触发额外的render()调用。如下:

componentWillReceiveProps: function(nextProps) {  
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

shouldComponentUpdate

当组件接收到新的属性和状态改变的话,都会触发调用shouldComponentUpdate(...),函数原型如下:

boolean shouldComponentUpdate(  
  object nextProps, object nextState
)

输入参数nextProps和上面的componentWillReceiveProps函数一样,nextState表示组件即将更新的状态值。这个函数的返回值决定是否需要更新组件,如果true表示需要更新,继续走后面的更新流程。否者,则不更新,直接进入等待状态。

默认情况下,这个函数永远返回true用来保证数据变化的时候 UI 能够同步更新。在大型项目中,你可以自己重载这个函数,通过检查变化前后属性和状态,来决定 UI 是否需要更新,能有效提高应用性能。

componentWillUpdate

如果组件状态或者属性改变,并且上面的shouldComponentUpdate(...)返回为true,就会开始准更新组件,并调用componentWillUpdate(),其函数原型如下:

void componentWillUpdate(  
  object nextProps, object nextState
)

输入参数与shouldComponentUpdate一样,在这个回调中,可以做一些在更新界面之前要做的事情。需要特别注意的是,在这个函数里面,你就不能使用this.setState来修改状态。这个函数调用之后,就会把nextProps和nextState分别设置到this.props和this.state中。紧接着这个函数,就会调用render()来更新界面了。

componentDidUpdate

调用了render()更新完成界面之后,会调用componentDidUpdate()来得到通知,其函数原型如下:

void componentDidUpdate(  
  object prevProps, object prevState
)

因为到这里已经完成了属性和状态的更新了,此函数的输入参数变成了prevProps和prevState。

componentWillUnmount

当组件要被从界面上移除的时候,就会调用componentWillUnmount(),其函数原型如下:

void componentWillUnmount()

在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等。

总结

到这里,RN 的组件的完整的生命都介绍完了,在回头来看一下前面的图,就比较清晰了,把生命周期的回调函数总结成如下表格:

生命周期调用次数能否使用 setSate()
getDefaultProps1(全局调用一次)
getInitialState1
componentWillMount1
render>=1
componentDidMount1
componentWillReceiveProps>=0
shouldComponentUpdate>=0
componentWillUpdate>=0
componentDidUpdate>=0
componentWillUnmount1
来自:http://www.race604.com/react-native-component-lifecycle/

扩展阅读

Moles框架,携程基于React Native的跨平台开发
通往全栈工程师的捷径 —— react 
React 入门实例教程
【REACT NATIVE 系列教程之六】重写shouldComponentUpdate指定组件是否进行重绘
React Native 的最佳轮播类组件:react-native-swiper
2016-04-07 01:19:14 u013531824 阅读数 4479

一、生命周期流程图

下面是通过ProcessOn绘制的React Native组件生命周期流程图,可以先大致看一下,有一个初步的概念,下文会详情介绍。

二、基础巩固

props
组件的不可变属性,在组件外部复制,在组件内部使用,当在组件内部props的改变,组件不会重新渲染。
是子组件与父组件通信的桥梁。
父组件向子组件传递数据的纽带。
ReactNativeActivity向Js传递数据的接收载体。

举个栗子具体说明,假设有父组件ComponentParent和一个子组件Search,代码结构如下。

//父组件
var ComponentParent = React.createClass({
    getInitialState: function () {
        return {
            data: 5,
        };
    },
    getSearchValue:function(val){
        this.setState({
        })
    },
    render: function () {
        return (
            <View>
                <View>
                    <Search getSearchValue = {this.getSearchValue} 
                            configData={this.state.data}></Search>
                </View>
            </View>
        );
    },
});

//子组件
var Search = React.createClass({
getInitialState(){
        return {
            value:""
        }
    },
getDefaultProps: function () {
        return {
            configData: 0
        };
    },
transferValue: function (val) {
        this.props.getSearchValue(val);
    },
render: function () {
        return (
            <View >
                <Text>{this.props.configData}</Text>
                <Text 
                  onPress={this.transferValue.bind(this,this.state.value)}>确定</Text>
            </View>
        );
    },
});
  • 子组件调用父组件的属性,关键代码{this.props.configData}可以获取父组件的{this.state.data}值在子组件中使用。而configDatathis.props的一个组成成员,可以随意定义名字及任意多个props成员。而在getDefaultProps方法中可以设置props的默认值。
  • 子组件调用父组件的方法, 同理,在父组件通过<Search getSearchValue = {this.getSearchValue}>向子组件中传递可调用的方法。子组件通过this.props.getSearchValue(val)来调用方法,并向父组件中的方法传值。
  • 从Activity或者Fragment等Native向Js传值,this.props负责接收。
    //在Activity中添加如下代码
    @Nullable
    @Override
    protected Bundle getLaunchOptions() {
        Bundle opt = new Bundle();
        opt.putString("nativeValue","You are Best!!");
        return opt;
    }

在index.android.js中去接收从Activity传入nativeValue值 。

var ComponentParent = React.createClass({
    getDefaultProps: function () {
        return {
            nativeValue:""
        };
    },
     render: function () {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>{this.props.nativeValue}</Text>
            </View>
        );
    },
});

state
组件的可变属性,用来存储组件自身所需要的数据,React会监听组件的state属性的变化,一旦状态变化,就会调用组件的render方法更新UI。

  • 使用代码示例 {this.transferValue.bind(this,this.state.value)}
  • 赋值的代码示例
 getValue: function (text) {
        var value = text;
        this.setState({
            value: value
        });
    },
  • 使用的属性,需要在getInitialState方法中进行初始化

注意任何状态的改变,都会引起render的执行,所以不建议在render内部改变state的值,容易造成无限刷新,导致内存泄露。

三、组件生命周期介绍

创建阶段
1、 getDefaultProps

作用于组件类,也就是调用React.createClass()的时候被调用。
每次创建组件的时候执行且只执行一次,方式如 reload Js。

用来处理props的默认值。

note :
如果在JS文件中定义了一个组件,但是没有使用它,此组件的getDefaultProps也会被调用。
组件内部不允许对props进行修改,只能通过调用她的父组件来修改,也就是从父组件向当前组件进行传值,在组件的内部去使用或展示这个值。

实例化阶段
作用于组件的实例,当组件被调用的时候执行
2、getInitialState
初始化组件的state值,返回值将赋值给this.state。
作用相当于自定义控件的构造函数及成员变量初始化。

3、componentWillMount
组件开始渲染render之前被调用。
所以控件展示之前的逻辑处理,应该在这个函数中实现。
作用相当于Fragment生命周期中的onCreate方法。

4、render
根据State的值,开始渲染,生成一个虚拟的DOM,并返回。
组件所需的控件及初始值在这里定义。
作用相当于MVVM开发模式中的Xml资源文件。
返回值:null、false、返回View结构

5、componentDidMount
在最初的render方法调用之后立即调用。
在这个方法中,父组件可以访问子组件的任意引用。
子组件的componentDidMount方法在父组件的此方法之前调用。
网络请求、事件订阅等操作可以在这个方法中调用。
作用相同与Fragment生命周期中的onViewCreate方法。

以上是创建一个组件,及不更新组件数据的情况下的整个生命周期,

更新阶段
6、componentWillReceiveProps
接收更新之后的props。
如果props没有更新,此方法不调用。

7、shouldComponentUpdate
当state的值有变化时,先执行此方法,此返回值为true/false,判断是否执行更新操作,即是否执行render渲染。
所以可以在此方法中编码,当状态改变时是否重新渲染的逻辑。

8、componentWillUpdate
执行更新render方法之前需要做的处理。
同componentWillMount方法,可以修改state值。

9、componentDidUpdate
组件的更新已同步到DOM中,可以进行DOM操作。

销毁阶段
10、componentWillUnMount
组件生命周期的最后一步,组件将走到生命的尽头,^_^,这是我们需要做一些回收的工作。
如取消事件绑定,关闭网络连接等操作。

以上说全部生命周期的介绍,我们在看一遍流程图,是否有一个新的认识。
组件生命周期

总结
1、 组件被创建后,如果不被调用,将只调用getDefaultProps()方法。
2、 componentWillMount()和componentWillUpdate()方法,是render调用之前最后一个方法,可以用来处理this.state赋值操作及业务逻辑。
2、 因为this.state状态的改变,会重新渲染组件,render()方法会执行,所以不要在render做this.state值改变操作,只用来展示。负责很有可能造成循环渲染,导致程序崩溃。

2018-04-18 14:59:42 theVicTory 阅读数 412

React Native的组件从创建到被渲染再到被销毁有一个过程,在不同的阶段完成不同的任务,通过了解其生命周期可以让我们知道应该在什么阶段对其进行哪些操作。一般人们将其分为三个阶段:

  • 初始化阶段:这个阶段用于准备组件所需要的数据,然后将组件渲染到页面上。
  • 运行阶段:组件一直循环监听,当组件中的数据被修改时,组件将重新渲染页面。
  • 销毁阶段:当不再需要组件时,组件会自动进行销毁。

从上图中可以看到组件在每个生命周期内都有响应的许多钩子函数,我们可以把组件需要执行的操作放在对应的钩子函数中,下面记录这些钩子函数:

1、初始化阶段

  • getDefaultProps:在此钩子中可以设置组件默认的属性Props
  • getInitialState:在这个钩子中可以对组件的state数据进行设置,通过this.setState()函数对state进行修改,通过this.state进行访问

注意:React在es6中删除了以上两个钩子,而通过类的构造函数constructor来初始化state,通过声明静态变量来设置props:

class App extends Component {       //ES6创建组件
  static defaultProps={             //ES6初始化props
    myProps:'myProps'
  };
  constructor(props){
    super(props);
    this.state={                    //ES6初始化state
      myData:'state'
    }
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.instructions}>
          {this.props.myProps}{this.state.myData}
        </Text>
      </View>
    );
  }
}
  • componentWillMount:组件挂载之前的钩子,需要在组件被渲染到页面之前的操作可以放在这里。
  • render:用于渲染组件的方法,返回一个JSX的语法的DOM,组件据此来渲染页面。
  • componentDidMount:组件挂载之后,需要在组件渲染后的操作可以放在这里。一般在这里进行网络数据请求与加载操作。

2、运行阶段

  • componentWillReceiveProps:组件在接收父组件更新props之前的执行。
  • shouldComponentUpdate:当props或state改变后,将进行此函数判断,通过返回true或false来控制是否对组件进行重新渲染。
  • componentWillUpdate:组件刷新前调用。
  • componentDidUpdate:组件刷新之后调用。

3、销毁阶段

  • componentWillUnmount:组件在被销毁之前调用的函数。
2017-08-17 16:01:13 ZY_FlyWay 阅读数 1323

前言:

         在面向对象编程中,任何对象的存在都会存在生命周期。类似我们iOS 的View,就会有LoadView,ViewWillAppear,ViewDidLoad等等生命周期。RN也不例外,这篇主要学习RN的生命周期,在开发中如果掌握了并熟练的运用生命周期函数的话,往往开发能事半功倍。

    React Native生命周期简介





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

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

生命周期回调函数(ES5写法)

下面来详细介绍生命周期中的各回调函数,先说下和上图对应的ES5写法。

getDefaultProps

在组件创建之前,会先调用 getDefaultProps(),这是全局调用一次,严格地来说,这不是组件的生命周期的一部分。在组件被创建并加载候,首先调用 getInitialState(),来初始化组件的状态。

componentWillMount

然后,准备加载组件,会调用 componentWillMount(),其原型如下:

void componentWillMount()  

这个函数调用时机是在组件创建,并初始化了状态之后,在第一次绘制 render() 之前。可以在这里做一些业务初始化操作,也可以设置组件状态。这个函数在整个生命周期中只被调用一次。

componentDidMount

在组件第一次绘制之后,会调用 componentDidMount(),通知组件已经加载完成。函数原型如下:

void componentDidMount()  

这个函数调用的时候,其虚拟 DOM 已经构建完成,你可以在这个函数开始获取其中的元素或者子组件了。需要注意的是,RN 框架是先调用子组件的 componentDidMount(),然后调用父组件的函数。从这个函数开始,就可以和 JS 其他框架交互了,例如设置计时 setTimeout 或者 setInterval,或者发起网络请求。这个函数也是只被调用一次。这个函数之后,就进入了稳定运行状态,等待事件触发。

componentWillReceiveProps

如果组件收到新的属性(props),就会调用 componentWillReceiveProps(),其原型如下:

void componentWillReceiveProps(  
  object nextProps
)

输入参数 nextProps 是即将被设置的属性,旧的属性还是可以通过 this.props 来获取。在这个回调函数里面,你可以根据属性的变化,通过调用 this.setState() 来更新你的组件状态,这里调用更新状态是安全的,并不会触发额外的 render() 调用。如下:

componentWillReceiveProps: function(nextProps) {  
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

shouldComponentUpdate

当组件接收到新的属性和状态改变的话,都会触发调用 shouldComponentUpdate(...),函数原型如下:

boolean shouldComponentUpdate(  
  object nextProps, object nextState
)

输入参数 nextProps 和上面的 componentWillReceiveProps 函数一样,nextState 表示组件即将更新的状态值。这个函数的返回值决定是否需要更新组件,如果 true 表示需要更新,继续走后面的更新流程。否者,则不更新,直接进入等待状态。

默认情况下,这个函数永远返回 true 用来保证数据变化的时候 UI 能够同步更新。在大型项目中,你可以自己重载这个函数,通过检查变化前后属性和状态,来决定 UI 是否需要更新,能有效提高应用性能。

componentWillUpdate

如果组件状态或者属性改变,并且上面的 shouldComponentUpdate(...) 返回为 true,就会开始准更新组件,并调用 componentWillUpdate(),其函数原型如下:

void componentWillUpdate(  
  object nextProps, object nextState
)

输入参数与 shouldComponentUpdate 一样,在这个回调中,可以做一些在更新界面之前要做的事情。需要特别注意的是,在这个函数里面,你就不能使用 this.setState 来修改状态。这个函数调用之后,就会把 nextProps 和 nextState 分别设置到 this.props和 this.state 中。紧接着这个函数,就会调用 render() 来更新界面了。

componentDidUpdate

调用了 render() 更新完成界面之后,会调用 componentDidUpdate() 来得到通知,其函数原型如下:

void componentDidUpdate(  
  object prevProps, object prevState
)

因为到这里已经完成了属性和状态的更新了,此函数的输入参数变成了 prevProps 和 prevState

componentWillUnmount

当组件要被从界面上移除的时候,就会调用 componentWillUnmount(),其函数原型如下:

void componentWillUnmount()  

在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等。


生命周期回调函数学习笔记小例(ES6)


学习就要与时俱进,试着接受和学习新东西,下面的例子都是用ES6写的。


1、设置默认属性


代码:

 class RNHybrid extends Component {
  
  render() {  
      return(  
        <View style={styles.container}> 
          <Text style={{padding:10, fontSize:42}}>
                {this.props.name}
          </Text>
        </View>  
      );  
   }
}


RNHybrid.defaultProps = {
  name: 'Mary',
};


效果:





ES5和ES6写法对比:

ES6

class Greeting extends React.Component {
  // ...
}

Greeting.defaultProps = {
  name: 'Mary'
};


ES5

var Greeting = createReactClass({
  getDefaultProps: function() {
    return {
      name: 'Mary'
    };
  },

  // ...

});


总结:
          props相当于iOS 里的属性,但是这个属性只是readonly。我们可以通过this.props来读取属性。


2、设置状态


   由图片我们知道,当我们修改状态的时候,会从新调用render函数重新渲染页面,所以一些和界面有关的动态变量需要设置成状态。

   如上一篇的例子,我在从新copy一遍:

看下效果:





代码:(生命周期现在还没有说我也是偏面的了解,以后会系统的学习,现在先不介绍)

[javascript] view plain copy
  1. constructor(props) {  
  2.         super(props);  
  3.         //设置当前状态是text  初始值为空  
  4.         this.state = {text: ''};  
  5.     }  
  6.   
  7.   render() {    
  8.       return(    
  9.         <View style={styles.container}>   
  10.           <TextInput style={styles.TextInputStyles}   
  11.               onChangeText={(Text)=>{  
  12.                 this.setState({text:Text});  
  13.               }}  
  14.           />   
  15.           <Text style={{padding:10, fontSize:42}}>  
  16.                 {this.state.text}  
  17.           </Text>  
  18.         </View>    
  19.       );    
  20.    }  

ES5和ES6写法对比:

ES6 

class myClass extends React.Component {
  constructor(props) {
    super(props);    this.state = {text:''};
  }
  // ...
}


ES5

var myClass = createReactClass({
  getInitialState: function() {
    return {text: ''};
  },
  // ...
});


ES5和ES6还有一个不同的地方,如果调用事件函数需要bind绑定

例如:

class RNHybrid extends Component {
  

  constructor(props) {
        super(props);
        this.state = {age:this.props.age};
    }

 handleClick() {
    alert(this.state.age);
  }

  render() {  
      return(  
        <View style={styles.container}> 
          <Text style={{padding:10, fontSize:42}} onPress={this.handleClick}>
                {this.props.name}
          </Text>
        </View>  
      );  
   }
}

这样写你点击的时候将会报错:



你需要将函数绑定:

1.可以在构造函数里绑定

 constructor(props) {
        super(props);
        this.state = {age:this.props.age};
        this.handleClick = this.handleClick.bind(this);
    }

2.还可以在调用的时候绑定

 <Text style={{padding:10, fontSize:42}} onPress={this.handleClick.bind(this)}>
                {this.props.name}
 </Text>


3、其他生命周期函数验证


代码:

import React, { Component } from 'react';
import {
   AppRegistry,
  StyleSheet,
  View,
  Text,
  TextInput,
} from 'react-native';

var  nowTime = new Date();
var  showText;

class RNHybrid extends Component {
  
  constructor(props) {  
        super(props);  
        console.log('state:'+nowTime);
        showText = 'state:'+nowTime+'\r\r';   
        //设置当前状态是text  初始值为空  
        this.state = {text: ''};  
  }


  componentWillMount(){
    console.log('componentWillMount:'+nowTime);
    showText = showText+'componentWillMount:'+nowTime+'\r\r';   
  } 

  componentDidMount(){
    console.log('componentDidMount:'+nowTime);
    showText = showText+'componentDidMount:'+nowTime+'\r\r';   
    alert(showText);
  } 

  shouldComponentUpdate(){
    console.log('shouldComponentUpdate:'+nowTime);
    showText = showText+'shouldComponentUpdate:'+nowTime+'\r\r';   
    return true;
  } 
   
  componentWillUpdate(){
    console.log('componentWillUpdate:'+nowTime);
    showText = showText+'componentWillUpdate:'+nowTime+'\r\r';       
  } 

  componentDidUpdate(){
    console.log('componentDidUpdate:'+nowTime);
    showText = showText+'componentDidUpdate:'+nowTime+'\r\r';       
  } 

  componentWillUnmount(){
    console.log('componentWillUnmount:'+nowTime);
    showText = showText+'componentWillUnmount:'+nowTime+'\r\r';       
  }

  render() {    
      return(    
        <View style={styles.container}>   
          <TextInput style={styles.TextInputStyles}   
              onChangeText={(Text)=>{  
                this.setState({text:Text});  
              }}  
          />   
          <Text style={{marginTop:10,padding:10, fontSize:15,borderColor:'gray',borderWidth:1}}>  
                {showText}  
          </Text>  
        </View>    
      );    
   }  
}

RNHybrid.defaultProps = {
  name: 'Mary',
  age:'18',
};


const styles = StyleSheet.create({
   container:{
   		marginTop:100,
   		flexDirection:'row',
      flexWrap:'wrap',
      justifyContent:'space-around',
   },
   TextInputStyles:{
      width:200,
      height:60,
      borderWidth:2,
      borderColor:'red',
   },
});

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


效果:




分析:

    当加载时候,按照 构造函数-> componentWillMount -> render->componentDidMount 这个顺序来的。
     细心的人可能会发现,界面上并没有显示componentDidMount,是因为执行了这个函数并没有重新render。
    当你输入的时候改变state就按照图上左下角部分进行。重新render的时候,就会看到componentDidMount出现。

    验证图上的分析是合理的,我们也放心了。

2019-03-29 11:41:45 qq_36870072 阅读数 126

任何生命体都会经历从出生到消亡的过程,而 React Native 框架中的组件同样具有这样的属性。

在组件生命周期的每个阶段,React Native 提供了多个生命周期函数,供开发者作为切入组件生命周期的钩子(hook),这样在对应的时间点程序就可以做对应的逻辑处理,从而实现相应的功能。

在 React Native 程序启动时,内部的虚拟 DOM 开始建立,生命周期就是建立在此虚拟 DOM 的整个生命周期之中,从虚拟 DOM 的初始化到虚拟 DOM 的卸载,React Native 为组件的不同状态建立了不同的生命周期。

React Native 中的生命周期

在图 1-1中,可以看到在 React Native 虚拟 DOM 的几个大的阶段中,都有对应的生命周期函数存在。

图 1-1 React Native 生命周期

  • 初始化阶段

此阶段进行组件的默认 props 和 state 的设定,可通过如下代码赋值。

static defaultProps = {  
    autoPlay: false,  
    maxLoop: 10,  
};
  • 加载阶段

此阶段为组件开始实例化的阶段,比如当该组件开始被其他组件调用的时候。主要包含以下三个生命周期函数。

  • componentWillMount:组件将要开始加载,需要在组件开始加载前添加一些业务逻辑,那么就可以添加在此函数中。
  • render:组件开始根据 props 和 state 生成页面的 DOM,并在最后返回此 DOM。在此函数中不可以修改 props 和 state 的值,只可以读取,并且返回的 DOM 只能有一个顶层元素,比如说只能由一个 div 包裹所有的元素进行返回。
  • componentDidMount:组件已加载完毕,在 render 函数之后立即执行此函数。一般可以在这里进行网络请求,因为组件 UI 渲染好之后再进行网络请求,一般不会造成 UI 的错乱问题。在此生命周期函数中修改设置了 state 的值后,UI 会立即进行重新渲染,所以是一个通过加载网络数据更新 UI 的好时机。
  • 更新阶段

此阶段一般因为用户操作或者父组件有更新时,当组件因为 props 或 state 的变更导致组件重新渲染时,会经历此阶段。而在更新渲染的几个重要时机,React Native 提供了如下的生命周期函数供开发者执行对应的逻辑操作。

  • componentWillReceiveProps:当接收到新的 props 值更新时,会执行到此生命周期函数,此时可以将接收到的 props 值赋值给 state。
  • shouldComponentUpdate:在此生命周期中,可以通过逻辑判断新的 props 和 state 的变更需不需要引起组件的 UI 更新,默认是都会引起更新的,但是 React Native 提供了此生命周期供开发者自主决定是否需要更新。如果让此函数返回 True,那么组件将进行更新,如果返回 False,那么组件就不更新。此生命周期在优化 App 性能时非常重要,因为可以通过此生命周期函数拦截掉很多不必要的组件 UI 更新。
  • componentWillUpdate:如果上面的生命周期函数 shouldComponentUpdate 返回了 True,那么此生命周期函数将继续执行,表示组件即将进行更新操作。在更新操作前,还有时机进行相关的逻辑处理。但是从逻辑上你也应该明白,这里不可以再修改 state 的值,而只可以做一些进行更新前的其他准备工作。
  • componentDidUpdate:组件更新完毕之后执行的生命周期函数。此函数有两个参数 prevProps 和 prevState,分别为更新前的 props 与 state。这里可以进行一些新旧值的比较,如果发现值有变化可以进行一些网络请求、加载数据等操作。

卸载阶段

  • componentWillUnmount:此生命周期函数在组件被卸载和注销前执行,这里可以进行一些所谓的扫尾工作,如关闭掉之前的网络请求、一些不必要存储的清空、循环执行的定时器的清除等等。
    至此,React Native 一个组件的完整生命周期执行完毕,你可以通过下面的代码体会 React Native 每个生命周期的执行过程。实际开发时只需要根据实际的项目需求在对应的生命周期函数中添加上自己的业务逻辑即可。