React-Native 生命周期函数
PS:ES6 已成为主流语法,推荐使用 ES6 语法。
RN 命周期示意图
RN 初始化阶段(调用一次)
-
defaultProps:组件实例创建之前调用,全局只调用一次,多个实例之间共享,如果父组件传递过来的 props 的 key 一样,将会被覆盖掉。在组件中我们可以用 this.porps 来初始化它的属性,由于组件初始化后,再次使用该组件不会调用 getDefaultProps 函数,所以组件自己不可以修改 props,只可以由其它组件调用它时在外部进行修改。
-
Constructor:构造函数,组件实例创建的时候调用的第一个函数,主要用于初始化 state ,我们尽量在初始化 state 的时候给它赋一个初始值,防止出现空值或者类型问题引起的错误。该函数不同于 getDefaultProps,在以后的过程中,会再次调用,所以我们可以将一些变量放在这里初始化,比如控件上显示的文字,可以通过 this.state.xx 来获取值,通过 this.setState 来修改值(一旦调用了 this.setState 方法,组件一定会调用 render 方法,对组件再次渲染,不过 React 的 DOM 会判断是否需要真正的渲染)。
//创建组件ES6写法 export default class BaseDetail extends React.Component { constructor(props) { super(props); //如果有extends 必须写super() this.state = { ...this, //如果继承的其他组件,需要父组件的state,需要...this loading: true,//首次loading ...... }; } }
-
componentWillMount:在React Native组件的生命周期中,这个函数只会被执行一次。它在初始渲染(render)前,Constructor 之后被执行,当它执行完后, render 函数会马上会被 RN 框架调用执行。如果在这个函数中通过setState函数修改状态变量,RN框架不会额外执行渲染,如果子组件也有componentWillMount函数,则会在父组件之后调用,如果需要从本地存储中读取数据用于显示、监听原生事件等,我们可以调用该函数。
componentWillMount() { BackHandler.addEventListener('hardwareBackPress', this._onBackAndroid); //监听安卓返回键 } _onBackAndroid = () => { Alert.alert('提示', '确定要退出系统吗?', [{ text: '取消', }, { text: '退出', onPress: () => { BackHandler.exitApp(); }, }]); };
-
render:组件渲染函数,返回一个虚拟 DOM,只允许返回一个最外层容器组件。render 函数尽量保持纯净,只渲染组件,不修改状态,不执行副操作(比如定时器等)
render( <View> ...... <Text>渲染页面</Text> ...... </View> )
-
componentDidMount:在 render 渲染完成之后,会根据虚拟 DOM 来生成着的 DOM ,生成完毕后会调用该函数(在浏览器端 React ,我们可以通过 this.getDOMNode()来拿到相应的 DOM 节点,在 RN 中用不到),在 RN 中一般用来 网络请求、调用接口加载数据、创建定时器等操作。
componentDidMount() { // 每30秒上传一次当前位置的经纬度 ...... this.state.timerGPS = setInterval(() => { if (this.state.location) { this.loginGPS(); } }, 30000); } //上传当前经纬度接口 loginGPS = async () => { try { if (GlobalVariable.token) { const ress = await Model.myInformation_getCoordinate({ userId: GlobalVariable.userId, longitude: this.state.location.longitude + '', latitude: this.state.location.latitude + '', ...... }); } else { return; } } catch (e) { ...... } ...... };
RN 运行阶段(调用多次)
-
componentWillReceiveProps(nextProps):初次渲染不会调用该方法,是 RN 故意设计这种机制的。在RN组件的初始渲染完成之后,当RN组件接收到新的props时,这个函数将被调用.参数就是新的props。如果新的props会导致界面重新渲染,这个函数将在渲染前执行.如果函数中修改状态,框架不会立刻执行状态机改变的渲染而是等函数执行完之后一起渲染。
-
boolean shouldComponentUpdate(object nextProps, object nextState):该函数传递过来两个参数,新的 state 和新的 props。state 和 props 的改变都会调到该函数。该函数主要对传递过来的 nextProps 和 nextState 作判断。如果返回 true 则重新渲染,如果返回 false 则不重新渲染。在某些特定条件下,我们可以根据传递过来的 props 和 state 来选择更新或者不更新,从而提高效率。
-
componentWillUpdate(object nextProps, object nextState):与 componentWillMount 方法类似,组件上会接收到新的 props 或者 state渲染之前,调用该方法。但是不可以在该方法中更新 state 和 props。
-
render:跟初始化时的功能一样。
-
componentDidUpdate(object prevProps,object prevState):和初始化阶段的 componentDidMount 类似,在render之后,真实DOM生成之后调用该函数。传递过来的是当前的 props 和 state。在该函数中同样可以使用 this.getDOMNode()来拿到相应的DOM节点。如果需要在运行中执行某些副操作,可以在该函数中完成。
RN 销毁阶段(调用一次)
-
componentWillUnmount:组件 DOM 中移除的时候调用。在这里进行一些相关的销毁操作,比如清除定时器、移除监听、清除临时缓存等等。
componentWillUnmount = () => { BackHandler.removeEventListener('hardwareBackPress', this._onBackAndroid); //移除安卓返回键监听事件 //清除定时器 if (this.state.timerGPS) { clearInterval(this.state.timerGPS); } };