/ react native

React Native跨平台移动应用开发实战 - 技术栈

本文隶属于文章系列 React Native跨平台移动应用开发实战 ,介绍RN应用开发用到的各项技术。读者在进行RN应用开发前,需要掌握这些技术。RN应用开发里面,RN只负责UI的绘制和跟原生系统的通信,对于一个完整的应用来说,还有许多技术层面的东西需要考虑,包括导航、应用状态管理和持久化、数据缓存、网络请求、错误处理等。

  1. JavaScript
  2. Flexbox Layout
  3. React
  4. Redux
  5. 项目结构

JavaScript

RN使用的JS引擎(下文提到引擎时如无特别说明即为该引擎)为Safari浏览器使用的引擎,当在Chrome浏览器里远程调试时,既然是运行在浏览器里,那就当然是V8引擎了。这两个引擎支持的JS语言特性非常相似,但也不排除会遇到两者行为不一致的地方,开发过程中应当避免使用这些特定于平台的特性。完整的说明详见官方文档,JavaScript Runtime

RN支持的JS特性范围横跨ES5、ES6和ES7,具体特性列表可参考官方文档。引擎并不直接支持这些特性,RN使用 [Babel](Babel JavaScript compiler) 来进行语法转换,使得采用这些特性编写的JS代码能够在引擎上运行。使用这些特性能够显著提升JS代码的开发效率、质量和安全性,值得花时间去了解和掌握。尤其是箭头函数、块作用域、参数展开、类、对象解构、异步函数等。

Flexbox Layout

CSS3里提出了一种新的Flexbox Layout,相比以前的Block Model,更容易适应不同屏幕大小,并且使用起来非常简单。这里有两篇学习文章,A Complete Guide to FlexboxCSS3 Flexible Box

RN里的Flexbox Layout跟CSS标准里的略有不同,默认的flex-direction是column,align-items是stretch,这是为了迎合手机应用页面内容一般都是向上靠拢,宽度方向填满的布局方式。官方文档,Layout with Flexbox

React

RN是React在移动平台的衍生,自然会依赖 React。React只是一个View Library,只负责页面的生成。React创建的是与特定平台无关的虚拟DOM Tree,这个虚拟DOM Tree最终将渲染成特定平台的UI。这样一来Rect就与平台无关,可以很方便的移植到Web以外的其它平台,比如iOS和Android。RN的诞生也是源于此。

React的核心就是JSX,类似于HTML,React使用它来描述UI。JSX本质上是JS语法的扩展,可以完全利用JS的能力,因此描述能力比HTML强大许多。具体参考官方文档 Introducing JSX,这个也是RN开发必备技能。

Redux

Redux 是JS应用的状态容器,并且状态是可预测的。随着单页面应用的兴起,应用状态越来越复杂,再加上状态可变和操作异步,应用状态就更加不可控了。
Redux提出了三大原则来使得应用状态的改变是可预测的,从而大大简化了应用状态的维护。

  • 真相只有一个 只有一个全局唯一的store来存放应用状态,应用状态的各部分按树形结构组织。
  • 状态只读 要改变状态只能通过发出action来完成,action描述了具体要做什么改变。
  • 通过纯函数来完成状态改变 这个纯函数称为reducer,reducer接收现有状态和action,返回新状态,但不改变原有状态。

这三大原则保证了应用状态修改的可预测性,因为任何修改都通过action做了记录,出现问题时很容易就能够定位到是哪个action导致。在应用状态比较复杂时,reducer可以拆分成多个,每个负责某部分状态的修改,以降低单个reducer的复杂度。React组件是可以拥有状态的,有状态的组件通常都比较复杂,使用Redux能够把组件状态抽取出来统一管理和维护,从而使得复杂的有状态组件变成了简单的无状态组件。Redux对于复杂应用开发来说非常关键,建议详细读完官方文档。

项目结构

./
├── LICENSE
├── README.md
├── android # 安卓工程目录
├── index.android.js # 安卓JS代码入口
├── index.ios.js # iOS JS代码入口
├── ios # iOS工程目录
├── node_modules
├── package.json
├── res # 资源,比如图片
├── src # JS源码
│   ├── ZQCApp.js # 应用入口,在这里面定义页面路由
│   ├── actions # redux action
│   ├── apis # API服务请求
│   ├── components # 无状态组件
│   ├── config.js # 应用配置
│   ├── containers # 有状态容器
│   ├── logger.js # 日志打印
│   ├── reducers # redux reducer
│   ├── setup.js # 创建store并加载应用
│   ├── store.js # store定义
│   └── utils # 一些小工具
├── zqc-app.sublime-project
└── zqc-app.sublime-workspace

基本上我们不会去动ios和android工程目录,平常大部分的工作都是在src目录下完成。
得益于使用Redux,我们能够将所有的组件变成无状态的,组件的状态都转移到容器里了。每个页面都有一个对应的容器,保存这个页面里所有组件的状态,组件的状态由容器通过属性的方式传递给它。这样会额外增加一些属性传递工作,尤其是组件层级比较多的时候,但换来的是页面状态的集中管理。只要查看页面对应的容器,就能很清楚的知道页面的状态。