android组件 实例化 组件实例化阶段_Text

React Native 组件的生命同期分为初始化阶段、存在阶段、销毁阶段。

实例化阶段

实例化阶段是RN组件生命周期中最常用的阶段,该阶段是组件的构建、展示,该阶段中的几个方法功能解析如下:

getDefaultProps:

该函数用于初始化一些默认的属性。在组件中可以利用 this.props.* 的方式获取在这个函数中定义的属性。

注意:this.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等),需要使用 ES5 的语法,如果用 ES6 的语法会报错。

 

存在和销毁阶段

 当程序执行完了初始化阶段最后调用的 componentDidMount 函数之后,程序就开始正常的运行起来,此时就进入了存在阶段。

存在阶段执行流程:

程序在运行过程中,如果对this.state 或者 this.props 进行了修改,那么就会触发存在阶段的多个函数(调用流程如上图所示)。

无论是修改this.state 还是 this.props,系统都会调用 shouldComponentUpdate 函数,判断视图是否需要渲染,如果不需要,则忽略本次修改状态;如果需要则在通过 componentWillUpdate 函数准备之后,重新调用 render 函数进行渲染。

注意:this.state 使用的是状态机制,即将组件看成一个状态机,一开始有一个初始状态,然后在用户互动的时候改变组件状态,从而触发重新渲染UI。

销毁阶段执行流程:

执行销毁阶段的情况有多种,如:当系统遇到错误而崩溃时;系统空间不足时;APP被用户推出时,等等等等。

当遇到上述问题时,系统就会进入销毁阶段,这个阶段只有一个过程:componentWillmount, 这个方法用来清空一些无用内容,如:点击事件的 Listener 等。

注意:销毁阶段是程序执行的出口,只要执行了销毁阶段,就表示程序已经自然或不自然的退出了。

 

状态机

上面说到,在RN生命周期初始化阶段的 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 方法设置。

ES5 和 ES6 代码的比较
ES6 的代码风格相对于 ES5 有很大的改变,实例化阶段的几个方法(render,getDefaultProps,getInitialState)在两个中的差别很大。

使用Es5编写:

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>
        );
    }
});

使用ES6 编写:

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节点

在RN中,组件并不是真正的DOM节点,而是存在于内存中的一种数据结构,叫做虚拟DOM。只有当它插入文档之后,才会称为真正的DOM。

如果想要通过组件获取真正的DOM节点,可以使用 ref 属性设置标记,然后在需要使用的地方通过 this.refs.* 访问这个组件。