es6导出组件 reactnative
2017-04-07 17:53:55 JLhaoran 阅读数 516

一:module.exports与exports 的区别

RN 首先组件的导出有两种方式    module.exports与exports  前者是ES5 写法  后者是ES6 写法,所以如果用ES5 导出一定要保持用ES5方式的引用方法  不然会报错的

因为

  1. module.exports 初始值为一个空对象 {}
  2. exports 是指向的 module.exports 的引用
  3. require() 返回的是 module.exports 而不是 exports

所以如果用 module.exports 导出组件  在其它组件引用时候用 require  如:

loginView.js 文件

class loginView extends Component {
    render() {
        return (
            <View style={styles.container}>
              .....
            </View>
        );
    }
}
// 输出类
module.exports = loginView;

在index.android.js中 引用如下

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

// 引入外部的js文件
let LoginView = require('./loginView');

class BTextInputDemo extends Component {
  render() {
    return (
       <LoginView />
    );
  }
}


AppRegistry.registerComponent('BTextInputDemo', () => BTextInputDemo);
ES6 的写法  loginView

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


export default class loginView extends Component {
  
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React 123!
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  }
});

index.android.js 文件

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

import LoginView from "./loginView";

export default class CQQLoginDemo extends Component {
  render() {
    return (
      <LoginView/>
    );
  }
}

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

二:export 与 export  default 的区别

export 可以在单个js文件中 导出多个组件

   例如:

  export class Template{}
  export class AnotherTemplate{}
 

这样在其他文件引用时,需要使用{}符号且组件名称必修和class名称一样,像这样子:

import {Template,AnotherTemplate} from './components/Templates';

而加default时,例如:

export default class Template{}

然后在其他文件引用,像这样子:

import Template from './components/Templates';

你也可以为这个组件另起一个别名,像这样子:

import TheTemplate from './components/Templates';

但是每个文件里只能有一个default组件,可以包含其他非default组件:

export default class Template{}
export class AnotherTemplate{}

然后引用的时候,如下:

import Template,{AnotherTemplate} from './components/Templates';
主意:
  • 有default和没有default的区别在于:有default在引用时可以自定义名称,而没有default时需要使用{}括起来且名称必修和class名称一致
  • 每个文件里只能有一个default组件,但可以有多个非default组件


2016-11-07 15:31:00 weixin_34301307 阅读数 4

在React Native中使用组件来封装界面模块时,整个界面就是一个大的组件,开发过程就是不断优化和拆分界面组件、构造整个组件树的过程。
所以学习理解组件的生命周期显得尤为重要!

一、组件的属性(props)和状态(state)

1. 属性(props)

它是组件的不可变属性(组件自己不可以自己修改props)。
组件自身定义了一组props作为对外提供的接口,展示一个组件时只需要指定props作为节点的属性。
一般组件很少需要对外公开方法(例外:工具类的静态方法等),唯一的交互途径就是props。所以说它也是父组件与子组件通信的桥梁
组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

2. 状态(state)

它是组件的内部状态属性,主要用来存储组件自身需要的数据。
除了初始化时可能由props来决定,之后就完全由组件自身去维护。
组件中由系统定义了setState方法,每次调用setState时都会更新组件的状态,触发render方法重新渲染界面
需要注意的是render方法是被异步调用的,这可以保证同步的多个setState方法只会触发一次render,这样做是有利于提高性能的。

二、组件的生命周期

对于自定义组件,除了必须实现的render方法,还有一些其他的可选方法可被调用。这些方法会在组件的不同时期之行,所以也可以说这些方法是组件的生命周期方法。
对于组件的生命周期来说一般分为四个阶段,分别为:
创建阶段、实例化阶段、运行(更新)阶段、销毁阶段。

1. 创建阶段

该阶段主要发生在创建组件类的时候,在这个阶段中会初始化组件的属性类型和默认属性。

defaultProps / getDefaultProps()

这里会初始化一些默认的属性,通常会将固定的内容放在这个过程中进行初始化和赋值,一个控件可以利用this.props获取在这里初始化它的属性,由于组件初始化后,再次使用该组件不会调用getDefaultProps函数,所以组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

在ES5里,属性类型和默认属性分别通过propTypes成员和getDefaultProps方法来实现。

//ES5
getDefaultProps: function() {
        return {
            autoPlay: false,
            maxLoops: 10,
        };
},
propTypes: {
        autoPlay: React.PropTypes.bool.isRequired,
        maxLoops: React.PropTypes.number.isRequired,
        posterFrameSrc: React.PropTypes.string.isRequired,
        videoSrc: React.PropTypes.string.isRequired,
},

在ES6里,可以统一使用static成员来实现.

//ES6
static defaultProps = {
        autoPlay: false,
        maxLoops: 10,
};  // 注意这里有分号
static propTypes = {
        autoPlay: React.PropTypes.bool.isRequired,
        maxLoops: React.PropTypes.number.isRequired,
        posterFrameSrc: React.PropTypes.string.isRequired,
        videoSrc: React.PropTypes.string.isRequired,
};  // 注意这里有分号

2. 实例化阶段

该阶段主要发生在组件类被调用(实例化)的时候。
组件类被实例化的时候,触发一系列流程:

1) constructor(props) / getInitialState()

这里是对控件的一些状态进行初始化,由于该函数不同于getDefaultProps,在以后的过程中,会再次调用,所以可以将控制控件的状态的一些变量放在这里初始化,如控件上显示的文字,可以通过this.state来获取值,通过this.setState来修改state值。

在ES5里,通过getInitialState对状态进行初始化

getInitialState: function() {
        return {
            loopsRemaining: this.props.maxLoops,
        };
},

在ES6里,通过constructor(构造器)对状态进行初始化

constructor(props){
        super(props);
        this.state = {
            loopsRemaining: this.props.maxLoops,
        };
}

2) componentWillMount()

准备加载组件。
这个调用时机是在组件创建,并初始化了状态之后,在第一次绘制 render() 之前。可以在这里做一些业务初始化操作,也可以设置组件状态。这个函数在整个生命周期中只被调用一次。
如果在这个函数里面调用setState,本次的render函数可以看到更新后的state,并且只渲染一次。

3) render()

render是一个组件必须有的方法,形式为一个函数,渲染界面,并返回JSX或其他组件来构成DOM,和Android的XML布局、WPF的XAML布局类似,只能返回一个顶级元素

4) componentDidUpdate()

调用了render方法后,组件加载成功并被成功渲染出来以后所执行的hook函数,一般会将网络请求等加载数据的操作,放在这个函数里进行,来保证不会出现UI上的错误

3. 运行(更新)阶段

该阶段主要发生在用户操作之后,或者父组件有更新的时候,此时会根据用户的操作行为,进行相应的界面结构调整。
触发的流程如下:

1) componentWillReceiveProps(nextProps)

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

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

2) shouldComponentUpdate(nextProps, nextState)

返回布尔值(决定是否需要更新组件)

输入参数 nextProps 和上面的 componentWillReceiveProps 函数一样,nextState 表示组件即将更新的状态值。这个函数的返回值决定是否需要更新组件,如果 true 表示需要更新,继续走后面的更新流程。否者,则不更新,直接进入等待状态。
默认情况下,这个函数永远返回 true 用来保证数据变化的时候 UI 能够同步更新。在大型项目中,你可以自己重载这个函数,通过检查变化前后属性和状态,来决定 UI 是否需要更新,能有效提高应用性能。

3) componentWillUpdate(nextProps, nextState)

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

4) render()

再确定需要更新组件时,调用render,根据diff算法,渲染界面,生成需要更新的虚拟DOM数据。

5) componentDidUpdate()

虚拟DOM同步到DOM中后,执行该方法,可以在这个方法中做DOM操作。
除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。

componentWillMount、componentDidMount和componentWillUpdate、componentDidUpdate可以对应起来。区别在于,前者只有在挂载的时候会被调用;而后者在以后的每次更新渲染之后都会被调用。
ps:绝对不要在componentWillUpdate和componentDidUpdate中调用this.setState方法,否则将导致无限循环调用。

4. 销毁阶段

该阶段主要发生组件销亡的时候,触发componentWillUnmount。当组件需要从DOM中移除的时候,通常需要做一些取消事件绑定,移除虚拟DOM中对应的组件数据结构,销毁一些无效的定时器等工作,都可以在这个方法中处理。

componentWillUnmount()

当组件要被从界面上移除的时候,就会调用 componentWillUnmount。
在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等

三、组件更新的方式(更新阶段详细)

本来是没有想要要详细写这部分内容的,不过看到另一篇文章,写得好好,就也放进来详细讲下,感谢原文作者
参考自:http://www.jianshu.com/p/4784216b8194 里的更新方式部分

更新组件(重新渲染界面)的方式有以下四种

  1. 首次渲染Initial Render,即首次加载组件
  2. 调用this.setState,状态发生改变(并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)
  3. 父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)
  4. 调用this.forceUpdate,强制更新

用图来表示这四种方式如下:

07153230_eYmL.png

更新组件方式.png

四、总结

1. 组件生命周期总体流程图

07153230_PE7C.png

组件的生命周期.png

2. 生命周期的回调函数总结

生命周期 调用次数 能否使用 setSate()
defaultProps / getDefaultProps 1(全局调用一次)
constructor / getInitialState 1
componentWillMount 1
render >=1
componentDidMount 1
componentWillReceiveProps >=0
shouldComponentUpdate >=0
componentWillUpdate >=0
componentDidUpdate >=0
componentWillUnmount 1

这篇文章参考了网上很多文章写出来的,特别是结合ES6的不同点一起写的。感觉还是挺有意义的,有不对的地方欢迎指出哈,欢迎大家提出建议。
其实如果是iOS开发人员,我觉得将组件的生命周期里的调用函数比较iOS的VC中的viewWillAppear等方法,还是挺容易理解的。(安卓应该也会有对应的概念才对)
如果感觉看了还是不太熟悉,建议自己写个demo,把所有方法都实现一次,控制台打出对应log,就一定可以更深刻的理解的!

转载于:https://my.oschina.net/sunshinewyf/blog/783158

2016-12-05 14:50:00 weixin_34148456 阅读数 18

在React Native中使用组件来封装界面模块时,整个界面就是一个大的组件,开发过程就是不断优化和拆分界面组件、构造整个组件树的过程。

所以学习理解组件的生命周期显得尤为重要!

一、组件的属性(props)和状态(state)

1. 属性(props)

它是组件的不可变属性(组件自己不可以自己修改props,只可由其他组件调用它时在外部改变)。

组件自身定义了一组props作为对外提供的接口,展示一个组件时只需要指定props作为节点的属性。

一般组件很少需要对外公开方法(例外:工具类的静态方法等),唯一的交互途径就是props。所以说它也是父组件与子组件通信的桥梁

组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

2. 状态(state)

它是组件的内部状态属性,主要用来存储组件自身需要的数据。

除了初始化时可能由props来决定,之后就完全由组件自身去维护。

组件中由系统定义了setState方法,每次调用setState时都会更新组件的状态,触发render方法重新渲染界面

需要注意的是render方法是被异步调用的,这可以保证同步的多个setState方法只会触发一次render,这样做是有利于提高性能的。

二、组件的生命周期

对于自定义组件,除了必须实现的render方法,还有一些其他的可选方法可被调用。这些方法会在组件的不同时期之行,所以也可以说这些方法是组件的生命周期方法。

对于组件的生命周期来说一般分为四个阶段,分别为:

创建阶段、实例化阶段、运行(更新)阶段、销毁阶段。

1. 创建阶段

该阶段主要发生在创建组件类的时候,在这个阶段中会初始化组件的属性类型和默认属性。

defaultProps / getDefaultProps()

这里会初始化一些默认的属性,通常会将固定的内容放在这个过程中进行初始化和赋值,一个控件可以利用this.props获取在这里初始化它的属性,由于组件初始化后,再次使用该组件不会调用getDefaultProps函数,所以组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

在ES5里,属性类型和默认属性分别通过propTypes成员和getDefaultProps方法来实现。

//ES5

propTypes: {

autoPlay: React.PropTypes.bool.isRequired,

maxLoops: React.PropTypes.number.isRequired,

posterFrameSrc: React.PropTypes.string.isRequired,

videoSrc: React.PropTypes.string.isRequired,

},

getDefaultProps: function() {        

               return {          

                                autoPlay: false,            

                                 maxLoops: 10,       

                           };

},

在ES6里,可以统一使用static成员来实现.

//ES6

static propTypes = {//用来指定props的类型

                                autoPlay: React.PropTypes.bool.isRequired,

                                 maxLoops: React.PropTypes.number.isRequired,

                                 posterFrameSrc: React.PropTypes.string.isRequired,

                                videoSrc: React.PropTypes.string.isRequired,

};  // 注意这里有分号

static defaultProps = {

                          autoPlay: false,

                           maxLoops: 10,

};  // 注意这里有分号

2. 实例化阶段

该阶段主要发生在组件类被调用(实例化)的时候。

组件类被实例化的时候,触发一系列流程:

1) constructor(props) / getInitialState()

这里是对控件的一些状态进行初始化,由于该函数不同于getDefaultProps,在以后的过程中,会再次调用,所以可以将控制控件的状态的一些变量放在这里初始化,如控件上显示的文字,可以通过this.state来获取值,通过this.setState来修改state值。

在ES5里,通过getInitialState对状态进行初始化

getInitialState: function() {

                    return {

                              loopsRemaining: this.props.maxLoops,

                                 };

},

在ES6里,通过constructor(构造器)对状态进行初始化

constructor(props){

        super(props);

        this.state = {

                 loopsRemaining: this.props.maxLoops,

                            };

    }

2) componentWillMount()

准备加载组件。

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

如果在这个函数里面调用setState,本次的render函数可以看到更新后的state,并且只渲染一次。

3) render()

render是一个组件必须有的方法,形式为一个函数,渲染界面,并返回JSX或其他组件来构成DOM,和Android的XML布局、WPF的XAML布局类似,只能返回一个顶级元素

4) componentDidUpdate()

调用了render方法后,组件加载成功并被成功渲染出来以后所执行的hook函数,一般会将网络请求等加载数据的操作,放在这个函数里进行,来保证不会出现UI上的错误

3. 运行(更新)阶段

该阶段主要发生在用户操作之后,或者父组件有更新的时候,此时会根据用户的操作行为,进行相应的界面结构调整。

触发的流程如下:

1) componentWillReceiveProps(nextProps)

当组件接收到新的props时,会触发该函数。在该函数中,通常可以调用setState()来完成对state的修改

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

componentWillReceiveProps: function(nextProps) {

               this.setState({

                        likesIncreasing: nextProps.likeCount > this.props.likeCount

                  });

}

2) shouldComponentUpdate(nextProps, nextState)

返回布尔值(决定是否需要更新组件)

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

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

3) componentWillUpdate(nextProps, nextState)

shouldComponentUpdate返回true或者调用forceUpdate之后,就会开始准更新组件,并调用 componentWillUpdate()。

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

4) render()

再确定需要更新组件时,调用render,根据diff算法,渲染界面,生成需要更新的虚拟DOM数据。

5) componentDidUpdate()

虚拟DOM同步到DOM中后,执行该方法,可以在这个方法中做DOM操作。

除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。

componentWillMount、componentDidMount和componentWillUpdate、componentDidUpdate可以对应起来。区别在于,前者只有在挂载的时候会被调用;而后者在以后的每次更新渲染之后都会被调用。

ps:绝对不要在componentWillUpdate和componentDidUpdate中调用this.setState方法,否则将导致无限循环调用。

4. 销毁阶段

该阶段主要发生组件销亡的时候,触发componentWillUnmount。当组件需要从DOM中移除的时候,通常需要做一些取消事件绑定,移除虚拟DOM中对应的组件数据结构,销毁一些无效的定时器等工作,都可以在这个方法中处理。

componentWillUnmount()

当组件要被从界面上移除的时候,就会调用 componentWillUnmount。

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

三、组件更新的方式(更新阶段详细)

本来是没有想要要详细写这部分内容的,不过看到另一篇文章,写得好好,就也放进来详细讲下,感谢原文作者

参考自:http://www.jianshu.com/p/4784216b8194里的更新方式部分

更新组件(重新渲染界面)的方式有以下四种

首次渲染Initial Render,即首次加载组件

调用this.setState,状态发生改变(并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)

父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)

调用this.forceUpdate,强制更新

用图来表示这四种方式如下:


2305876-03d8bf1b3e9cc5cf.png

四、总结

1. 组件生命周期总体流程图


2305876-a1b8cddecf1ac527.png

2. 生命周期的回调函数总结

生命周期                                                            调用次数                               能否使用 setSate()

defaultProps / getDefaultProps                          1                                                 (全局调用一次)

constructor / getInitialState                                1                                                    否

componentWillMount                                          1                                                     

render                                                                    >=1                                                否

componentDidMount                                         1                                                       

componentWillReceiveProps                             >=0                                                 

shouldComponentUpdate                                  >=0                                                 否

componentWillUpdate                                        >=0                                                 否

componentDidUpdate                                         >=0                                                 否

componentWillUnmount                                      1                                                       否

2016-08-11 14:30:00 weixin_34160344 阅读数 0

在React Native中使用组件来封装界面模块时,整个界面就是一个大的组件,开发过程就是不断优化和拆分界面组件、构造整个组件树的过程。
所以学习理解组件的生命周期显得尤为重要!

一、组件的属性(props)和状态(state)

1. 属性(props)

它是组件的不可变属性(组件自己不可以自己修改props)。
组件自身定义了一组props作为对外提供的接口,展示一个组件时只需要指定props作为节点的属性。
一般组件很少需要对外公开方法(例外:工具类的静态方法等),唯一的交互途径就是props。所以说它也是父组件与子组件通信的桥梁
组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

2. 状态(state)

它是组件的内部状态属性,主要用来存储组件自身需要的数据。
除了初始化时可能由props来决定,之后就完全由组件自身去维护。
组件中由系统定义了setState方法,每次调用setState时都会更新组件的状态,触发render方法重新渲染界面
需要注意的是render方法是被异步调用的,这可以保证同步的多个setState方法只会触发一次render,这样做是有利于提高性能的。

二、组件的生命周期

对于自定义组件,除了必须实现的render方法,还有一些其他的可选方法可被调用。这些方法会在组件的不同时期之行,所以也可以说这些方法是组件的生命周期方法。
对于组件的生命周期来说一般分为四个阶段,分别为:
**创建阶段、实例化阶段、运行(更新)阶段、销毁阶段。 **

1. 创建阶段

该阶段主要发生在创建组件类的时候,在这个阶段中会初始化组件的属性类型和默认属性。

defaultProps / getDefaultProps()

这里会初始化一些默认的属性,通常会将固定的内容放在这个过程中进行初始化和赋值,一个控件可以利用this.props获取在这里初始化它的属性,由于组件初始化后,再次使用该组件不会调用getDefaultProps函数,所以组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

在ES5里,属性类型和默认属性分别通过propTypes成员和getDefaultProps方法来实现。

//ES5
getDefaultProps: function() {
        return {
            autoPlay: false,
            maxLoops: 10,
        };
},
propTypes: {
        autoPlay: React.PropTypes.bool.isRequired,
        maxLoops: React.PropTypes.number.isRequired,
        posterFrameSrc: React.PropTypes.string.isRequired,
        videoSrc: React.PropTypes.string.isRequired,
},

在ES6里,可以统一使用static成员来实现.

//ES6
static defaultProps = {
        autoPlay: false,
        maxLoops: 10,
};  // 注意这里有分号
static propTypes = {
        autoPlay: React.PropTypes.bool.isRequired,
        maxLoops: React.PropTypes.number.isRequired,
        posterFrameSrc: React.PropTypes.string.isRequired,
        videoSrc: React.PropTypes.string.isRequired,
};  // 注意这里有分号

2. 实例化阶段

该阶段主要发生在组件类被调用(实例化)的时候。
组件类被实例化的时候,触发一系列流程:

1) constructor(props) / getInitialState()

这里是对控件的一些状态进行初始化,由于该函数不同于getDefaultProps,在以后的过程中,会再次调用,所以可以将控制控件的状态的一些变量放在这里初始化,如控件上显示的文字,可以通过this.state来获取值,通过this.setState来修改state值。

在ES5里,通过getInitialState对状态进行初始化

getInitialState: function() {
        return {
            loopsRemaining: this.props.maxLoops,
        };
},

在ES6里,通过constructor(构造器)对状态进行初始化

constructor(props){
        super(props);
        this.state = {
            loopsRemaining: this.props.maxLoops,
        };
}
2) componentWillMount()

准备加载组件。
这个调用时机是在组件创建,并初始化了状态之后,在第一次绘制 render() 之前。可以在这里做一些业务初始化操作,也可以设置组件状态。这个函数在整个生命周期中只被调用一次。
如果在这个函数里面调用setState,本次的render函数可以看到更新后的state,并且只渲染一次。

3) render()

render是一个组件必须有的方法,形式为一个函数,渲染界面,并返回JSX或其他组件来构成DOM,和Android的XML布局、WPF的XAML布局类似,只能返回一个顶级元素

4) componentDidUpdate()

调用了render方法后,组件加载成功并被成功渲染出来以后所执行的hook函数,一般会将网络请求等加载数据的操作,放在这个函数里进行,来保证不会出现UI上的错误

3. 运行(更新)阶段

该阶段主要发生在用户操作之后,或者父组件有更新的时候,此时会根据用户的操作行为,进行相应的界面结构调整。
触发的流程如下:

1) componentWillReceiveProps(nextProps)

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

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

返回布尔值(决定是否需要更新组件)

输入参数 nextProps 和上面的 componentWillReceiveProps 函数一样,nextState 表示组件即将更新的状态值。这个函数的返回值决定是否需要更新组件,如果 true 表示需要更新,继续走后面的更新流程。否者,则不更新,直接进入等待状态。
默认情况下,这个函数永远返回 true 用来保证数据变化的时候 UI 能够同步更新。在大型项目中,你可以自己重载这个函数,通过检查变化前后属性和状态,来决定 UI 是否需要更新,能有效提高应用性能。

3) componentWillUpdate(nextProps, nextState)

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

4) render()

再确定需要更新组件时,调用render,根据diff算法,渲染界面,生成需要更新的虚拟DOM数据。

5) componentDidUpdate()

虚拟DOM同步到DOM中后,执行该方法,可以在这个方法中做DOM操作。
除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。

componentWillMount、componentDidMount和componentWillUpdate、componentDidUpdate可以对应起来。区别在于,前者只有在挂载的时候会被调用;而后者在以后的每次更新渲染之后都会被调用。
ps:绝对不要在componentWillUpdate和componentDidUpdate中调用this.setState方法,否则将导致无限循环调用。

4. 销毁阶段

该阶段主要发生组件销亡的时候,触发componentWillUnmount。当组件需要从DOM中移除的时候,通常需要做一些取消事件绑定,移除虚拟DOM中对应的组件数据结构,销毁一些无效的定时器等工作,都可以在这个方法中处理。

componentWillUnmount()

当组件要被从界面上移除的时候,就会调用 componentWillUnmount。
在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等

三、组件更新的方式(更新阶段详细)

本来是没有想要要详细写这部分内容的,不过看到另一篇文章,写得好好,就也放进来详细讲下,感谢原文作者
参考自:http://www.jianshu.com/p/4784216b8194 里的更新方式部分

更新组件(重新渲染界面)的方式有以下四种

  1. 首次渲染Initial Render,即首次加载组件
  2. 调用this.setState,状态发生改变(并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)
  3. 父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)
  4. 调用this.forceUpdate,强制更新

用图来表示这四种方式如下:


2428275-d11e03f614e79ffb.png
更新组件方式.png

四、总结

1. 组件生命周期总体流程图

2428275-f08403a3ea1b80f4.png
组件的生命周期.png

2. 生命周期的回调函数总结

|生命周期 |调用次数 |能否使用 setSate() |
|: ------:|:------:|:------:|
|defaultProps / getDefaultProps| 1(全局调用一次) | 否
|constructor / getInitialState |1 |否
|componentWillMount |1 |
|render |>=1 |否
|componentDidMount |1 |
|componentWillReceiveProps |>=0 |
|shouldComponentUpdate |>=0 |否
|componentWillUpdate |>=0 |否
|componentDidUpdate |>=0 |否
|componentWillUnmount |1 |否


这篇文章参考了网上很多文章写出来的,特别是结合ES6的不同点一起写的。感觉还是挺有意义的,有不对的地方欢迎指出哈,欢迎大家提出建议。
其实如果是iOS开发人员,我觉得将组件的生命周期里的调用函数比较iOS的VC中的viewWillAppear等方法,还是挺容易理解的。(安卓应该也会有对应的概念才对)
如果感觉看了还是不太熟悉,建议自己写个demo,把所有方法都实现一次,控制台打出对应log,就一定可以更深刻的理解的!

正在写React Native的学习教程ing,是一边研究一边编写的,已有的成果如下(不断更新哈,望鼓励):
1) React Native 简介与入门
2) React Native 环境搭建和创建项目(Mac)
3) React Native 开发之IDE

4) React Native 入门项目与解析
5) React Native 相关JS和React基础
6) React Native 组件生命周期(ES6)
7) React Native 集成到原生项目(iOS)
8) React Native 与原生之间的通信(iOS)
9) React Native 封装原生UI组件(iOS)

转载于:https://www.jianshu.com/p/72f8c1da0b65

2018-04-21 22:17:00 weixin_34075268 阅读数 5

React Native中的文本输入框使用和iOS比较相近,可能是因为 RN 首先封装iOS端的缘故(这点对iOS开发者来说是个好消息)

TextInput也是继承自 View,所以 View 的属性 TextInput 也能使用,一些样式类的属性可以参照 View 的相关属性

为了更好的讲解 TextInput,先创建一个基本的文本输入框

// 视图
  export default class App extends Component {
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput style={styles.textInputStyle}></TextInput>
            </View>
        );
    }
}

// 样式
var styles = StyleSheet.create({
    container: {
        flex:1
    },

    textInputStyle: {
        // 设置尺寸
        width:width,
        height:40,
        marginTop:100,
        // 设置背景颜色
        backgroundColor:'green'
    }
});

Value:文本输入的默认值(注:如果设置了此属性,会造成无法输入的尴尬,一般会搭配JS动态设置)

          export default class App extends Component {
                 render(){
                  return(
                    <View style={styles.container}>
                    {/* 文本输入框 */}
                    <TextInput
                    style={styles.textInputStyle}
                    value="设置了Value"
                    ></TextInput>
                   </View>
               );
           }
    }

keyboardType:设置键盘类型(决定使用哪种键盘)

      export default class App extends Component{
         render(){
          return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    keyboardType="number-pad"
                ></TextInput>
            </View>
        );
    }
}

multiline:如果值为真,文本输入可以输入多行,默认值为假

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    multiline={true}
                ></TextInput>
            </View>
        );
    }
}

password:如果值为真,文本输入框就成为一个密码区域,默认值为假

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    password={true}
                ></TextInput>
            </View>
        );
    }
}

placeholder:在文本输入之前提示用户文本框功能,也就是占位文字

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    placeholder="请输入账号"
                ></TextInput>
            </View>
        );
    }
}

placeholderTextColor:占位字符串的文本颜色

   export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    placeholder="请输入账号"
                    placeholderTextColor="red"
                ></TextInput>
            </View>
        );
    }
}

autoCapitalize:控制TextInput是否要自动将特定字符切换为大写

none:不自动使用任何东西
sentences:每个句子的首字母(默认)
words:每一个单词的首字母
characters:所有字符

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                placeholder="none"
                autoCapitalize="none"
            ></TextInput>
            {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                placeholder="sentences"
                autoCapitalize="sentences"
            ></TextInput>
            {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                placeholder="words"
                autoCapitalize="words"
            ></TextInput>
            {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                placeholder="characters"
                autoCapitalize="characters"
            ></TextInput>
            </View>
        );
    }
}

autoCorrect:如果为false,会关闭拼写自动修正。默认值是true。

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                placeholder="没有自动改正拼写"
                autoCorrect={false}
            ></TextInput>
            {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                placeholder="自动改正拼写"
                autoCorrect={true}
            ></TextInput>
            </View>
        );
    }
}

autoFocus:如果为true,在componentDidMount后会获得焦点。默认值为false。

export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    autoFocus={true}
                ></TextInput>
            </View>
        );
    }
}

clearButtonMode:清除按钮出现的时机

never:不出现
while-editing:编辑的时候出现
unless-editing:没有编辑时出现
always:总是出现

export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
        <TextInput
            style={styles.textInputStyle}
            placeholder="never"
            clearButtonMode="never"
        ></TextInput>
        {/* 文本输入框 */}
        <TextInput
            style={styles.textInputStyle}
            placeholder="while-editing"
            clearButtonMode="while-editing"
        ></TextInput>
        {/* 文本输入框 */}
        <TextInput
            style={styles.textInputStyle}
            placeholder="unless-editing"
            clearButtonMode="unless-editing"
        ></TextInput>
        {/* 文本输入框 */}
        <TextInput
            style={styles.textInputStyle}
            placeholder="always"
            clearButtonMode="always"
        ></TextInput>
            </View>
        );
    }
}

clearTextOnFocus:如果为true,每次开始输入的时候都会清除文本框的内容

export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    clearTextOnFocus={true}
                ></TextInput>
            </View>
        );
    }
}

editable:如果值为假,文本是不可编辑,默认值为真

export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    editable={false}
                ></TextInput>
            </View>
        );
    }
}

enablesReturnKeyAutomatically:如果为true,键盘会在文本框内没有文字的时候禁用确认按钮。默认值为false。

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                enablesReturnKeyAutomatically={true}
            ></TextInput>
            {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                enablesReturnKeyAutomatically={false}
            ></TextInput>
            </View>
        );
    }
}

returnKeyType:决定返回键的样式

default
go
google
join
next
route
search
send
yahoo
done
emergency-call

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                returnKeyType="go"
            ></TextInput>
            {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                returnKeyType="join"
            ></TextInput>
            {/* 文本输入框 */}
            <TextInput
                style={styles.textInputStyle}
                returnKeyType="done"
            ></TextInput>
            </View>
        );
    }
}

secureTextEntry:如果值为真,文本输入框就会使输入的文本变模糊,以便于像密码这样敏感的文本保持安全,类似 password 属性,默认值为假

export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    keyboardType="number-pad"
                ></TextInput>
            </View>
        );
    }
}

onChange:当文本框内容变化时调用此回调函数

    export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    onChange={() => {alert('文本框内容改变')}}
                ></TextInput>
            </View>
        );
    }
}

onChangeText:当文本框内容变化时调用此回调函数。改变后的文字内容会作为参数传递

export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    onChangeText={(Text) => {alert('文字改变')}}
                ></TextInput>
            </View>
        );
    }
}

onFocus:当文本框获得焦点的时候调用此回调函数

export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    onFocus={() => {alert('文本框获得焦点')}}
                ></TextInput>
            </View>
        );
    }
}

onBlur:当文本框失去焦点的时候调用此回调函数

 export default class App extends Component{
    render(){
        return(
            <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    onBlur={() => {alert('失去焦点')}}
                ></TextInput>
            </View>
        );
    }
}

onEndEditing:结束编辑时,调用回调函数

               export default class App extends Component{
                render(){
                  return(
                  <View style={styles.container}>
                {/* 文本输入框 */}
                <TextInput
                    style={styles.textInputStyle}
                    onEndEditing={() => {alert('结束文本编辑')}}
                ></TextInput>
             </View>
            );
      }
}
没有更多推荐了,返回首页