react-native 开发小结(Android)

7,600 阅读6分钟

在windows上开发react-native已经有一些时候了。作为一个Android原生开发者,在开发的过程中,虽然有点蛋疼,但毕竟积累了一点点经验,再不说出来,我就要侧漏了......

1,前言

react-native开发使用的是JS,但是并不是纯正的JS,而是一种JSX语言,就是在JS中嵌入XML语言,因此,只要有一些JS的语法基础的原生开发者,就可以肯容易理解JSX的语法了,在RN中,推荐使用ES6的语法。

对于JS而言,一切皆对象,函数也是对象,而对象的内部是通过key-value的形式来组成的,也可以说是通过json格式来组成。对象内部每一个键值对(key:value)称作一个属性(RN中最重要的属性是state和props)。

2,性能

使用react-native开发的最大的有点在于开发效率,加入APP并不复杂的话,那么完全可以使用纯JS开发,也就是Android和iOS公用一套界面和逻辑。极大的提高了开发效率。在性能上,(Android中一般的操作)RN的表现比原生弱一些,但是远好于H5。所以总体来看,其实RN的未来还是可以期待的。

3,RN运行机制简述

RN是运行JS的,Android是运行Java字节码的,所以,实际上JS代码的最终运行是通过一层封装,把JS的代码映射成原生代码,而界面上的元素最终使用的也是原生的组件,而不是自己渲染(所以在性能上,RN比H5要好很多)。

4,Component简介

在Android中,主要交互容器是activity或Fragment,而在RN中,界面的交互容器是Component:组件。我觉得Component和原生的Fragment其实很像,都存在于activity中,都受制于activity的生命周期,都可卸载和装载。

4.1,Component生命周期

component生命周期

由上图可知,大致分三个过程:初始化,运行中,卸载。

  • 初始化阶段:
    • 在新版的Component中ES6语法中,getDefaultProps,getInitialState 是不应该被复写的。RNAPI要求我们props,state的初始化在Component的constructor函数中完成(props,state这俩大宝贝下文在做解释),因此在初始化阶段可以做的就是在constructor或者componentDidMount函数中完成相关初始化工作。
    • componentDidMount函数是组件第一次绘制完成之后被调用的,整个周期只被调用一次,在这里可以做一些网络请求操作等。
  • 运行阶段:
    • 重点在于修改state内容,来刷新界面
  • 卸载阶段
    • 在componentWillUnmount方法中做一些移除操作,或者什么都不做。

在这里,已经有前辈写出了比较详细的博文了,有兴趣请前往React Native 中组件的生命周期

4.2,state和 prop

这两个属性之所以重要,是因为stat和界面的刷新有关,prop则和组件的封装有关。

state初始化在构造函数中,通过setState来修改里面具体的值。具体如下:

state

而修改state内容则是这样:

setstate

当state中的内容被修改后,当前组件就会按照生命周期来刷新页面,这样,所有和界面刷新的任务就全部交到state这一个属性手里了。这是一个很不错的设计。

而prop这个属性,则是用于封装组件的时候对外暴露组件的可输入属性。即就像这样:

prop示例

就这样,封装组件中的所有你想暴露给别人输入的属性都可以定义在prop之中。

4.3,component间的跳转

在原生开发中,界面的跳转主要依赖Intent作为桥梁,而在RN中,则全部依靠Navigator这个组件来实现页面之间的跳转逻辑。

navigator实例

  • initRoute这个属性指定了初始化的页面,在这个例子中,进入第一屏的页面将是TabBarView,
  • configureScene这个属性用于指定默认跳转动画
  • renderScene这个属性传入的是一个方法,根据得到的不同的组件(component)来渲染不同的场景。

Navigator这个导航器是全局的,整个APP中只有一个,会根据界面的跳转传递到每个Component内部的prop中。Navgator会维护一个栈,这一点和原生的Activity的任务栈极其相似,可以对照理解。

  • 数据传递 上面的代码中有这样一段:
< Component navigator = {navigator} route = {route}
        {...route.passProps} />

{...route.passProps}保证passProps里每个key都会被视作prop的一个属性,具体如下:

跳转到SecondPageComponent界面

navigator.push({
    name: 'SecondPageComponent',
    component: SecondPageComponent,
    passProps: {   //注意passProps和之前定义的保持一致
        msg:'ladingwu is handsome'
    }
});

而在SecondPageComponent界面界面中,这样来取数据:

export default class SecondPageComponent extends React.Component {

    componentDidMount() {
            //这里获取传递过来的参数
            var message=this.prop.msg;
        }
}

怎么样,简单极了吧。当然,在原生开发中,还有startActivityForResylt()这个方法可以再从第二个界面返回时获取数据,那么在RN中是否能做到呢?也很简单,依然是通过传递参数,只不过这个时候的参数,应该是一个回调函数(js中,函数也可以当作参数,一切皆对象)

跳转到SecondPageComponent界面

navigator.push({
    name: 'SecondPageComponent',
    component: SecondPageComponent,
    passProps: {   //注意passProps和之前定义的保持一致

        getMsg:(msg)=>{console.log(msg)}
    }
});

而在SecondPageComponent界面界面中返回数据:

export default class SecondPageComponent extends React.Component {

    componentDidMount() {
            //这里获取传递过来的参数
            this.prop.getMsg('ladingwu is still handsome');
        }
}

不要太简单哦。。。。

5,总结

当然,RN还有很多可以说的,比如动画(性能有点感人),网络请求,数据存储等等,就不一一举例说明了。

说一点感想,使用RN开发这段时间,感觉这玩儿确实可以提高工作效率,毕竟Android和iOS使用一套界面,而且很多功能在RN上都有完备的实现,基本上,只要APP的业务逻辑不复杂,或者并不涉及到很多硬件操作或对性能要求很高的话,使用纯RN开发是完全可以的。假如H5是未来的话,那么在未来来临之前,RN才是更好的选择,当然,RN并不能完全取代原生开发,因为它只是在原生和H5之间找平衡的产物,它当然好,但也不是最优解。

你是不是该学?

应该,即使只是冲着JS也要去学一把,如今,JS不仅霸占了web端,还入侵了移动端和后台开发,我就问你怕不怕?


最后推荐几个学习RN必备网站:

React-Native中文站(非官方)

React-Native官方网站

江清清的技术专栏

google搜索引擎