一 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 废弃了模板
较强的构建能力JS是一种简便、强大的编程语言拥有构建抽象的能力这一点在大型应用中非常重要
易于扩展和维护通过相应的VIew逻辑将标签组合起来React可以更方便的扩展和维护这些view每个组件作为一个独立的视图。这使得更容易进行迭代产品扩展时只需关注组件本身
代码复用、测试和关注分离separation of concerns
更安全将一些可理解的标签和内容引入到JS中没有人工字符串拼接从而减少了XSS漏洞
传统的web方式构建UI是将一堆抽象的HTML 模板堆起来React将UI划分为一个个组件这意味着React使用了一种真实、完整特性的语言去渲染View相比于模板它有以下优点
多平台复用
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上没有一个足够完善的线程模型
在web上很难利用多线程并行执行工作
虽然web的Worker机制可以在后台执行一部分程序逻辑但依然无法去做一些高负荷的数值计算譬如在主线程以外的地方去进行图片解码、文本布局等等。这可能是开发一个高性能和快速响应的web app最大的难点。
2.5 web + Native
如果我们希望既能具备原生应用的用户体验又能获得我们用React开发web应用的开发体验该如何做呢facebook曾考虑过以下几种方案
webview
虽然灵活可以以web开发的方式进行开发但所有的渲染都由web相关的技术来完成无法得到一个真正原生的用户体验
将React移植到原生
IOS上已经成功移植开源项目ComponentKitComponentKit — 一个功能性和声明性的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的UIKitAndroid UI等等。
三 RN 的架构
逻辑架构
Virtural DOM
Virtual DOM是DOM在内存中的一种轻量级表达方式可以通过不同的渲染引擎生成不同平台下的UI
Vitual Dom对于RN的更新效率有很大帮助React 中的Dom并不保证马上影响真实的DomReact会等到事件循环结束利用diff算法通过当前新Dom树与之前的Dom树作比较计算出更新真实的DOM的最小步骤
Virtual Dom 的抽象为跨平台提供了可能达到 Learn once, write anywhere
四 开发基础
4.1 语言
4.1.1 JS
ES5/6/7
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)。
4.2 开发方式
4.2.1 组件
UI 和 样式 分离
组件的构成
UI元素
属性
Props
状态
State
组件的特性
生命周期
状态机
数据绑定
主线程问题
4.2.2 样式
StyleSheet
类似CSS语法灵活多样式复用
FlexBox弹性布局
响应式布局模型
灵活性高几乎可实现任意布局
Google已经放出了android平台的Flexbox
React Native并没有完整实现CSS而是使用JavaScript来给应用添加样式。这种做法当初是有争议的你可以参考这个幻灯片来了解一下这样做的理由。
4.2.3 API
基本组件
View
、Text
、ScrollVIew
、Image
、List
、Drawer
常用模块
Toast
、Storage
、Navigator
动画完整的动画API
缩放
移动
旋转
插值
手势识别
PanResponder
类似Android事件处理机制
4.2.4 RN 开发工具 Nuclide
Atom编辑器上的一个package
Atom是Github官方开源的一个编辑器
五 RN 缺点
Bug定位困难
版本不稳定
安装包太大
issue很多