React-Native 之 生命周期

前言

  • 学习本系列内容须要具有必定 HTML 开发基础,没有基础的朋友能够先转至 HTML快速入门(一) 学习react

  • 本人接触 React Native 时间并非特别长,因此对其中的内容和性质了解可能会有所误差,在学习中若是有错会及时修改内容,也欢迎万能的朋友们批评指出,谢谢算法

  • 文章初版出自简书,若是出现图片或页面显示问题,烦请转至 简书 查看 也但愿喜欢的朋友能够点赞,谢谢react-native

React Native 组件执行顺序介绍


  • 全部的程序都有生命周期,这是开发人员关注的点,好比iOS中有一个 ViewDidLoad 来初始化,在React Native中又是在哪里?这边从文档中截取的一张图并注释了下,很好地描述了React Native组件的执行顺序

React Native执行顺序.png

  • 从图中能够看出,在React Native中,组件的生命周期大体能够分为3个阶段(实例化阶段、存在阶段、销毁阶段),其中最常接触的为实例化阶段,这个阶段负责组件的构建和展现的时间,须要咱们根据几个函数的调用过程,控制好组件的展现和逻辑处理

实例化阶段函数功能分析


  • getDefaultProps:该函数用于初始化一些默认属性,一般会将固定的内容放在这个函数中进行初始化和赋值网络

    • 在组件中,咱们能够利用 this.props 获取在这里初始化它的属性,因为组件初始化后,再辞使用该组件不会调用 getDefaultProps 函数,因此组件本身不能够修改props,只可由其余组件调用它时再外部进行修改
  • getInitialState:该函数用于对组件一些状态进行初始化数据结构

    • 该函数不一样于getDefaultProps,在之后的过程当中,会再次调用,因此能够将控制控件状态的一些变量放在这里初始化,好比控件上显示的文字,能够经过this.state来获取值,经过 this.setState 来修改state值


    var SMZQ = React.createClass({
    
    		// 用于设置一些值固定不变或上下界面值传递
    		getDefaultProps(){
    			return{
        			number1: 1,
        			number2: 2
    			}
    		},
    
    		// 用于设置一些可变或者用来刷新界面
    		getInitialState(){
    			return{
        			sum:0
    			}
    		},
    
    		render() {
    			return (
        			<View style={styles.container}>
            			<Text>number1:{this.props.number1}</Text>
            			<Text>number2:{this.props.number2}</Text>
            			<Text>sum:{this.state.sum}</Text>
            			<TouchableOpacity
                			onPress={() => {this.setState({sum: this.props.number1 + this.props.number2})}}
            			>
                			<Text>计算和</Text>
            			</TouchableOpacity>
            			<TouchableOpacity
                			onPress={() => {this.setState({sum: this.state.sum + 1})}}
            			>
                			<Text>和的基础上+1</Text>
            			</TouchableOpacity>
        			</View>
    			);
    		}
    	});

    效果:
    getDefaultProps和getInitialState使用.gif框架

    • 注:一旦调用了 this.setState方法,组件必定会调用render方法,对组件进行再次渲染,不过,React框架会根据DOM的状态自动判断是否须要真正渲染
  • componentWillMount:至关于OC中的 ViewWillAppear 方法,在组件简要被加载到视图以前调用,没有太多的功能异步

  • render:它是每一个组件必需具有的方法,本质上是个函数,而且返回JSX或者其余组件来构成DOM,和Android的XML布局相似函数

    • 在该函数中,只能经过this.state和this.props来访问以前在函数中初始化的数值
    • 注:只能返回一个顶级元素
  • componentDidMount:在调用了render方法,组件加载成功并被成功渲染出来以后,所要执行的后续操做,通常都会在这个函数中进行,好比常常要面对的网络请求等加载数据操做布局

    • 由于UI已经成功渲染,并且这里面是异步的,索引放在这个函数进行数据的请求等复杂的操做,不会出现UI错误

存在阶段函数功能分析


  • componentWillReceiveProps:指父元素对组件的props或state进行了修改
  • shouldComponentUpadate:通常用于优化,能够返回false或true来控制是否进行渲染
  • componentWillUpdate:组件刷新前调用,相似componentWillMount
  • componentDidUpdate:更新后的hook

销毁阶段函数功能分析


  • 用于清理一些无用的内容,如:点击事件Listener,只有一个过程:componentWillUnmount

经常使用知识点分析


  • this.state:开发中,组件确定要与用户互动,React的一大创新就是将组件当作一个状态机,一开始有一个初始状态,而后用户互动,致使状态变化,从而触发从新渲染UI,举个例子性能

    var SMZQ = React.createClass({
    
    		// 用于设置一些可变或者用来刷新界面
    		getInitialState(){
    			return{
        			isPositive: true,
        			content:'5是否是负数'
    			}
    		},
    
    		render() {
    			return (
        			<View style={styles.container}>
            			<TouchableOpacity
                				onPress={() => {this.dealWithState(this.state.isPositive, 5)}}
            			>
                			<Text>{this.state.content}</Text>
            			</TouchableOpacity>
        			</View>
    			);
    		},
    
    		dealWithState: function (data:Boolean, num:int) {
        		var isPositive, content;
    
        		if (num > 0){
            		isPositive = false;
            		content = '值不是负数';
        		}else {
            		isPositive = true;
            		content = '值是负数';
        		}
        		this.setState({
            		isPositive: isPositive,
            		content: content
        		});
    		}
    	});

    效果:
    this.state探究.gif

    • 当用户点击组件,致使状态变化,this.setState方法就修改状态值,每次修改之后,会自动调用this.render方法,再次渲染组件
    • 能够把组件当作一个状态机,根据不一样的status有不一样的UI展现,只要使用setState改变状态值,根据diff算法算出有差值后,就会执行ReactDom的render方法,从新渲染页面
    • 注:因为this.props和this.state都用于描述组件的特性,可能会产生混淆,一个简单的区分方法就是 —— this.props表示那些一旦定义,就再也不更改的特性,而this.state是会随着用户互动而产生改变的特性
  • 获取真实的DOM节点

    • 在React Native中,组件并非真实的DOM节点,而是存在于内存中的一种数据结构 ,叫虚拟DOM
    • 只有当它插入文档后,才会变成真实的DOM
    • 根据React的设计,全部DOM变更,都先在虚拟DOM上发生,而后再将实际发生变更的部分,反应在真实DOM上,这种算法叫作DOM diff,它能够极大提升网页的性能表现
    • 有时须要从组件获取真实DOM节点,这时就须要用到ref属性,能够看下面的示例加深理解


    var SMZQ = React.createClass({
    		render() {
    			return (
        			<View ref="mainView" style={styles.container}>
            			<TouchableOpacity
                			onPress={() => {this.dealWithState()}}
            			>
                			<Text>值</Text>
            			</TouchableOpacity>
            			<TextInput ref="mytextInput"></TextInput>
        			</View>
    			);
    		},
    
    		dealWithState: function () {
        		// 让输入框得到焦点
        		this.refs.mytextInput.focus();
        		// 查看内容属性
        		console.log(this.refs.mainView);
    		}
    	});

    效果:
    打印结果.png

    • 能够看出,组件View的子节点有一个文本输入框,用于获取用户的输入,这时就必须获取真实的DOM节点,虚拟DOM是拿不到用户输入的,为了作到这一点,文本输入框必须有一个ref属性,而后this.refs.refName就会返回这个真实的DOM节点
    • 须要注意的是,因为this.refs.refName属性获取的是真实DOM,全部必须等到虚拟DOM插入文档后,才能使用这个属性,不然会报错。上面代码中,经过组件指定Click事件的回调函数,确保只有等到真实DOM发生Click事件以后,才会读取this.refs.refName属性

补充


  • 什么是DOM Diff算法(下面内容是搜索的内容)
    • Web界面由DOM树来构成,当其中某一部分发生变化时,其实就是对应的某个DOM节点发生了变化。在React中,构建UI界面的思路是由当前状态决定界面。先后两个状态就对应两套界面,而后由React来比较两个界面的区别,这就须要对DOM树进行Diff算法分析
    • 即给定任意两棵树,找到最少的转换步骤。可是标准的的Diff算法复杂度须要O(n^3),这显然没法知足性能要求。要达到每次界面均可以总体刷新界面的目的,势必须要对算法进行优化。这看上去很是有难度,然而Facebook工程师却作到了,他们结合Web界面的特色作出了两个简单的假设,使得Diff算法复杂度直接下降到O(n)
      • 两个相同组件产生相似的DOM结构,不一样的组件产生不一样的DOM结构
      • 对于同一层次的一组子节点,它们能够经过惟一的id进行区分 -算法上的优化是React整个界面Render的基础,事实也证实这两个假设是合理而精确的,保证了总体界面构建的性能
相关文章
相关标签/搜索