一 React Native
1.1 RN 的目标
React Native使你能够在Javascript和 React 的基础上获得完全一致的开发体验,构建世界一流的原生APP
React Native着力于提高多平台开发的开发效率 —— 仅需学习一次,编写任何平台 (Learn once, write anywhere
1.2 RN 的优点
- 编译,开发效率更高
- 更短的迭代周期,方便新功能测试
- 热部署
- 采用web的方式来开发native应用
- 和native相同的用户体验和用户习惯
- “一次学习,随处可写”,降低开发成本
- 可预测性
1.2 RN 开发原则
- 复用性
- 在编写任何 React Native 的代码之前,你应该考虑如何“尽可能地复用代码”。
- 组件化的平台抽象
- 在考量 React Native app 中的可视化组件时,关键在于使用平台抽象。我们可以与设计师确定 app 中可复用的组件,比如:按钮,容器,列表的每一行等等。并且,只在有需要的地方将这些组件做分化。
以上原则可以帮助我们在Android IOS两个平台上尽可能的复用一套代码,降低开发成本,这也是RN开发中很重要的一点
二 RN 的架构起源
2.1 React
Facebook开源的 web UI 框架。它使得工程师们可以把更多的时间和精力用于关注他们的产品本身,而不是应付框架带来的各种问题
- 多平台复用
- React包装了复杂而易变的DOM API,提供一个声明式的结构,使得整个程序模型变得抽象而简单,达到多平台复用
- 代码可预测
- 这种可预测性使得我们在快速迭代产品时更多的信任已有的代码,最终我们的应用程序也变得更为可靠。更易于扩展,我们的团队规模也更容易进行调整
-
自更新
-
任何时候底层数据变化时,React 会 自动处理所有用户界面的更新 。只需描述应用程序在任一个时间点应该长的样子。
-
在传统的JS应用中,需要观察数据变化,并将变化通知DOM去更新。
在React中,组件第一次初始化的时候,会执行render方法生成轻量级的View表示。通过这种表示,标签对应的string会生成,并且注入到document中。当数据变化的时候,render方法会再次被调用。
- Diff更新
- 数据变化后, 仅会更新变化的部分
- 为了尽可能快的执行更新,React会使用新的返回值和之前的返回值对比,生成一个最小变更集合到DOM中
2.3 原生开发
原生开发缺点
- 开发效率低,web开发可以用React或Relay来简化开发流程
原生开发的优点
- 原生应用相比web更好的用户体验
- 原生平台特有的UI组件,譬如地图、日期选择器、开关,还有导航栈这些基本组件,有更好的体验,Google官方会不断更新
-
web上没有一个足够完善的线程模型
- 在web上很难利用多线程并行执行工作
- 虽然web的Worker机制可以在后台执行一部分程序逻辑,但依然无法去做一些高负荷的数值计算,譬如在主线程以外的地方去进行图片解码、文本布局等等。这可能是开发一个高性能和快速响应的web app最大的难点。
2.5 web + Native ?
如果我们希望既能具备原生应用的用户体验,又能获得我们用React开发web应用的开发体验,该如何做呢?facebook曾考虑过以下几种方案:
- webview
- 虽然灵活,可以以web开发的方式进行开发,但所有的渲染都由web相关的技术来完成,无法得到一个真正原生的用户体验
-
将React移植到原生
- IOS上已经成功移植,开源项目 ComponentKit , ComponentKit — 一个功能性和声明性的UI工具
- Android上还没有,需要重新开发,开发成本高,上手成本高,无法使用web顶层的技术栈和工具,最重要的是,仍然无法改善开发中最大的问题——每次修改之后,重新编译和构建工程。
-
用脚本封装原生
-
JS语言本身跨平台,可以采用像web的开发方式
-
直接利用JS基础平台和技术
2.6 用脚本封装原生的问题
- UI线程阻塞
- 直接在原生环境和解释环境之间采用同步调用,UI线程很可能会被JavaScript执行阻塞住,要提高界面的响应效率,必须把JavaScript放到主线程之外执行。但这样做最直接的困难是资源访问竞争。如果我们的JavaScript访问正在被其它线程使用的资源(譬如一个渲染的View的尺寸),系统就只能加锁来确保方案安全,而这又会导致UI线程的卡顿
- 资源开销
- 每次原生和JavaScript虚拟机之间互相访问,在访问过程中都会带来极大的开销。如果经常跨线程访问,就会造成大量的开销
- 必须改变一些基础层次的编程模型来确保系统在线程之间传递消息永远是异步的,这样就可以在一帧之内尽可能打包更多的消息发送,来尽可能减少一些跨线程交互的开销
React模型
- 非阻塞
- React是完全异步的,因此React的模型可以很好地解决上面提到的线程问题
- Virtual DOM
- React中的DOM是一种抽象的概念,这种抽象可以使React绑定到任何需要的视图系统上,比如IOS的UIKit,Android UI等等。
三 RN 的架构
逻辑架构
Virtural DOM
Virtual DOM是DOM在内存中的一种轻量级表达方式,可以通过不同的渲染引擎生成不同平台下的UI
Vitual Dom对于RN的更新效率有很大帮助,React 中的Dom并不保证马上影响真实的Dom,React会等到事件循环结束,利用diff算法,通过当前新Dom树与之前的Dom树作比较,计算出更新真实的DOM的最小步骤
Virtual Dom 的抽象为跨平台提供了可能,达到 Learn once, write anywhere
四 开发基础
4.1 语言
4.1.1 JS
- ES5/6/7
- ES语法
- ES6和ES5的区别
- ECMAScript 6入门
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
4.1.2 JSX
- JSX 是一个看起来很像 XML 的 JavaScript 语法扩展,在 JavaScript 代码里写着 XML 格式的代码称为 JSX
- 在React 中可以接使用纯粹的 JS。但更建议使用 JSX , 因为它能定义简洁且我们熟知的包含属性的树状结构语法。
- 对于非开发者(比如设计师)同样容易理解。
- XML 有固定的标签开启和闭合。这能让复杂的树更易于阅读,优于方法调用和对象字面量的形式。
- React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。
- 深入理解JSX
4.2 开发方式
4.2.1 组件
UI 和 样式 分离
4.2.2 样式
Google已经放出了android平台的 Flexbox
React Native并没有完整实现CSS,而是使用JavaScript来给应用添加样式。这种做法当初是有争议的,你可以参考这个 幻灯片 来了解一下这样做的理由。
4.2.3 API
- 基本组件
-
View
、 Text
、 ScrollVIew
、 Image
、 List
、 Drawer
- 常用模块
-
Toast
、 Storage
、 Navigator
4.2.4 RN 开发工具 Nuclide
Atom编辑器 上的一个package
Atom是Github官方开源的一个编辑器
五 RN 缺点
- Bug定位困难
- 版本不稳定
- 安装包太大
- issue很多
六 参考文献
RN官方文档
RN中文文档
React中文文档
React组件化概念
深入理解React
FlexBox Guide
Promises
React Native For Android 架构初探
react-native-bringing-modern-web-techniques-to-mobile
F8项目整体介绍
为什么构建React
JSX
原文 http://www.lightskystreet.com/2016/05/26/RN-Introduction/