React Native入门指南

转载自:http://www.jianshu.com/p/b88944250b25javascript

前言

React Native 诞生于 2015 年,名副其实的富二代,主要使命是为父出征,与 Apple 和 Google 抗衡,为开发者带去一套跨平台、动态更新的 Javascript 框架,口号是:Learn once, write anywhere:Build mobile apps with React。在试图推翻 Android 和 iOS 压制的同时,还提携了一把自家兄弟:React。html

从诞生之日 React Native 就充满了期待和争议。期待是无数开发者但愿不用忍受频繁发版的噩梦,也不用同时为两个平台开发业务逻辑几无差异的两个 App;争议是 React Native 真的能以一己之力救大众于水火吗?React Native 在跨平台时还能保持良好的用户体验吗?前端

固然咱们知道,这种问题向来都是仁者见仁,智者见智。比起一味的疑惑、争论,还不如来好好看看这货到底是个啥?甚至本身动手来玩一把。java

本文主要针对两类读者:node

  • 想要入门 RN 的人,在阅读官方文档前先对 RN 造成一个总体的印象
  • 对 RN 心存好奇,在犹豫是否要入坑的开发者,能够经过本文对 RN 更客观全面的认识

目录

  • React Native 好在哪
    • 跨平台+动态更新
    • 代码复用
    • RN vs Weex
    • RN vs Hybrid
    • RN 劣势
  • React Native 运行机制
  • RN 开发环境搭建
  • 引入 React Native
    • Build from Scratch
    • 集成到已有项目
  • Javascript、React 及 ES六、JSX 语法
  • UI 层
  • 网络请求层
  • Debugging 调试
    • In-App 报错
    • Console.log
    • 大杀器:Chrome 逐行调试
  • 从 JS 调用 Native 方法或显示自定义 Native View
    • Native Modules:JS 里直接调用 Native(Java/Swift) 方法
    • Native UI Component:JS 里直接调用自定义的 Native View
  • React Native 适合你吗?
  • 为何要写这篇文章

1、React Native 好在哪

下面咱们来看下 Hybrid 及 React Native 等开发模式包含了哪些常规移动开发所不具有的优点。react

1. 跨平台+动态更新

传统的客户端开发模式是怎样的呢?android

Android 与 iOS Team 分别编写客户端代码,打包,分发到 Play Store 和 Apple Store,经过更新 JSON 数据来更新页面。ios

不过,当客户端发生严重问题而服务器上没法 quick fix 时,就不得不从新发版。git

对国外 Android 市场而言还好,由于能经过 Play Store 快速更新;国内 Android 市场则因为分发渠道太杂,很难及时把新版本当即推送给全部用户,固然这也是为什么热修复技术在国内盛行而国外冷清的缘由;而 Apple Store 则须要必定的审核时间,并且最近又在抓 iOS 热修复框架如 JsPatch、Rollout 等。程序员

相比而言,Hybrid 和 RN/Weex 模式除了能下发 Json 数据来刷新界面内容,更能直接下发业务逻辑代码,直接实现总体 App 的更新。并且,它们不用在意 Android 和 iOS 两个平台,由于一份 JS 代码写好后,把 JS Bundle 放在服务器上,全部的客户端当即更新。

2. 代码复用

通常而言,同一款产品的 Android 和 iOS 两端除 UI 有些许不一样外,多数业务逻辑几乎彻底一致,这便形成了人力的浪费。

而最近 Instagram 的官博 React Native at Instagram 一文中已经提到,利用 RN (React Native 缩写,下同) 开发的 feature 能够实现 85% - 99% 的代码复用率。这意味着咱们能够用更少的人力成原本达到相同的效果。

3. RN vs Weex

实现上面的效果有两种开发框架:混合开发框架 Cordova 和基于 Javascript 的 React-Native、Weex 框架。

下面我从本身的实践经验出发作些比较,也欢迎读者提出本身见解。

最开始以为 RN 的学习成本比较大,因此首先考虑了 Weex 框架,听说是阿里巴巴良心出品。不过在尝试后不得不选择了放弃,缘由有这几点:

  • Bug 较多。咱们最早测试了最基本的 ListView,在 iOS 运行良好,而一样的 Demo 代码到了 Android 这边的下拉刷新就出现了问题,这使得咱们开始警戒;
  • 社区、文档弱,GitHub Issue 基本是中文。固然我毫无歧视中文之意。我认为,一套项目开源是真正意义是但愿借助开源社区的力量,一块儿来完善改进,所以要优先推崇英文,使项目国际化,获得全世界开发者的共同支持,这样才是可持续的模式。而 Weex 的 Issue 里放眼望去基本 90% 都是中文,不管提问者仍是项目维护者。这一点直接把国外优秀的开发者拒之门外,也很难让我看到多么长远的将来。
    下面是摘取的 RN 里的一则中文 issue:

Issue is for bug report, not for Q&A
  • Contributor 差异。由于上面一点,Weex 的 Contributor 只有 91 我的,而 React-Native 的 Contributor 有 1214 人。Contributor 是用来干吗的?除了支持新功能,还有就是修复 bug 啊。Weex/RN 都是但愿一统 Android + iOS 的,这么伟大的目标,这么艰巨的工程,不是几我的能够轻轻松松搞定的。
  • 公司背景(来自YY)。你们都知道 RN 来自 Facebook,Weex 来自阿里巴巴。若是想一窥它们的将来,须要先想一下这种技术对他们各自的意义。你们都清楚,Facebook、Google、Apple 是当今当之无愧的巨头,在移动互联网这波浪潮里,Google 掌握了 Android 法器,Apple 控制了 iOS 神器,Facebook 呢?并无这些系统级入口。固然 Windows 的经历也让 Facebook 并不那么倾向去开发一个新的移动操做系统来竞争。那怎么办?React Native 应运而生,打出的口号就是: Learn once, write anywhere。什么意思,没错,就是明确告诉你学一次就能够同时开发两个平台了。这一点可一直都是移动端开发人员和创业公司的理想。有人说了,Apple 这么强势,RN 要是太嚣张,分分钟把你禁掉。这时咱们就要来看看 RN 的Showcase 了,哪些 App 应用了 RN 呢?Facebook, Instagram, Airbnb, Walmart, QQ, 京东等,这回 Apple 要禁 RN 就要稍微掂量下这些大厂的意见吧。

固然,我是很但愿国内也能推出优质的开源项目来和国外大厂抗衡的,不过真正优质的大型开源项目每每除了开发者的我的能力,和公司的战略和制度关系也很大。

4. RN vs Hybrid

这里的 Hybrid 开发主要针对 Cordova 框架,其实在放弃 Weex 以后咱们仍是没考虑 RN,而是转过去了解 Cordova,不过作了大体了解后也放弃了。主要硬伤有两点:

  • 性能短板。你们知道 Hybrid 是基于 WebView 的,在 Android 上的性能缺陷很是明显;而 RN 是利用 JSCore 转化成 Native 运行的,性能相对而言好很多;
  • 用户体验。了解移动产品的人都知道用户体验的重要性,RN 的体验和原生的几乎没有差异,而 Webview 的实现是网页开发思路,体验会相差很大。

性能和用户体验是移动 App 的命根子。

所以,综合考虑下来,咱们仍是决定相信 Facebook 并采用 RN。

5. RN 劣势

上面我提到了 RN 的一些优点,不过做为开发者更加须要明确其劣势,我总结了下大概有如下几点劣势:

  • 学习成本。Weex 的写法就是相似常规的 Html/JS,对于前端人员来讲很容易上手,就算了非前端人员来讲也花不了多久。而 RN 是在 React.js 上进行改进造成的一套语法,和常规前端差异较大,所以须要好几天的学习适应。固然我以为优秀的程序员的基本素质之一就是能快速学习、练习并熟练一种新语言的。我我的的话大概花了两三天的时间已经能完成一套涵盖网络、JS与Native通讯的页面了,对于 React.js 语法也上手很快。
  • 安装包 Size。对于 iOS 而言影响不算很大,对于 Android 来讲,我尝试后发现引入 RN 会给 apk 带来 6MB 左右的增幅,不过利用 split apk 的技术就能缩小到到 1MB 左右的增幅。
  • 首次加载耗时。你们知道 RN 须要从服务器下载 JS bundle,而后在本地转化成 Native code 运行的,因此在第一次打开 App 时须要花费一些时间进行下载和刷新。固然咱们能够在发布 client 时内置一个写好的 js 文件在本地做缓存用。

2、React Native 运行机制

对于一个用 RN 搭建的移动 App,在启动后会从服务器下载最新的 JS Bundle 文件,而后由本地 JavascriptCore 引擎对 JS 文件进行解析,并利用 Bridge 映射到对应的 Native 方法和 UI 控件。获得的效果是:

  1. 一样的 RN 代码,下发到 Android 和 iOS 不一样平台中,会自动调用对应 Native 的 UI 控件,保证了各平台用户体验的连贯性;
  2. 开发者就算是移动端小白,只要有 Web 基础,经过编写一套 RN 端代码就能够同时完成 Android 与 iOS App 的开发;
  3. 因为能够利用 JS bundle 同时下发数据和业务逻辑,这意味着你能够像 Web 开发同样,实时迭代更新你的移动端 App,无需在了解各自平台的热修复技术;
  4. Native Modules,这是 RN 强大的一个扩展性,容许你经过简单的代码就能实如今 JS 里直接调用你本身的 Native 方法;
  5. Native Components,若是你本身实现了一些复杂的 Native UI 组件,而这些组件还没有被 RN 支持,你能够利用 Native Components 快速把原生组件引入到 RN 中并能够直接在 JS 里更新这些组件的状态。

3、RN 开发环境搭建

首先 IDE 方面,RN 推荐了一些工具:

  • Nuclide 是 Facebook 内部用来开发 RN 的工具,Debug 功能强大。只不过这是一款Atom 的插件,意味着你必须先安装 Atom,再来安装这款开发插件;
  • Deco 是专为开发 RN 诞生的工具,能够快速搜索开源的第三方 RN 组件并直接插入到代码中,用 MacOS 的同窗能够尝试下。我本人最开始也是试用这个,上手简单、小巧简洁。不足的是功能有点简单,不管是 Debug 功能仍是代码检查之类的都不具有;
  • Sublime 能够经过第三方包来达到不错的开发效率,各方面还算可圈可点;
  • Visual Studio 这款也是蛮强大的 IDE,以前有用过的小伙伴能够试一下。

本人的话目前采用的是 Sublime,由于我的经常使用 Sublime,并且第三方插件很丰富,轻量方便。下面简单说下配置,感兴趣的小伙伴能够看下。

  1. Babel 用来高亮 React JSX 语法,支持 ES6,而 React-Native 就是搭建在 React.js基础上的;
  2. React-Native-Snippets 能够快速生成 RN 的一些模版代码;
  3. ESLint 超级强大的 Lint 工具,支持 ES六、JSX 语法检查,并且还有 React 和 RN 的插件,比纯粹的 JSXHint/JSLint 都强大;

固然,用 Atom 的小伙伴天然要首先考虑 Nuclide

4、引入 React Native

引入 RN 有两种方法:从零构建;集成到已有项目。

1. Build from Scratch

先说第一种,从零开始构建,比较简单,遵循官方文档 Getting Started 基于你本身的操做系统和平台一步步安装相关的依赖,而后利用以下命令:

react-native init AwesomeProject

你就建立好一个 RN 工程项目了,结构以下:


RN 目录结构

里面有四个文件夹:

  • android / ios:各自存放了一个相关平台的工程 project,能够直接下拉 JS Bundle 并运行,对于移动端小白而言能够不用管里面的具体实现;
  • node_modules:里面是自动生成的 node 依赖之类的文件,经过读取 package.json 里的配置来生成;
  • js:这个文件夹最为重要,咱们的开发都在这个文件夹里,把写好的 js 文件打包下发给 client 就会自动生效。
2. 集成到已有项目

有不少公司是但愿在现有 App 的基础上集成 RN 来开发一些特定的 Feature,这种状况就不能参考上面的方法了。在 RN 的官方文档里有一节 Integration with Existing Apps , 只须要按照一步步作便可。

以 Android 为例,大概要作如下几步:

  1. 添加 gradle 依赖:compile "com.facebook.react:react-native:+" // From node_modules.
  2. 建立空的 Activity ,指定 JS bundle 和入口 Component 名字即会自动在这个 Activity里去加载 JS bundle 文件;
  3. 在 Activity 里监听 onBackPressed 事件,用来与 JS 端协做处理返回键点击事件。
  4. 启动 server,运行 App 便可。

总之须要说明的是,即便是移动端小白,也能够遵循文档里的指示完成这一步。接下来的大部分时间只要关心 JS 端开发就好了。

5、Javascript、React 及 ES六、JSX 语法

咱们知道 RN 采用了 React 和 ES6 的语法,因此咱们必须先对这些语法有必定了解才能去读 RN 的代码。

关于 Javascript,我推荐 W3School 里的 JS语法 和 MDN 里的 JS手册,你们只要对一些基础语法作些了解就能够。

关于 React,我推荐 阮一峰 写的 React 入门实例教程,基本上把文章读一遍,再本身动手写一遍,就能理会到 React 的大体用法了。

关于 ES6ES7JSX等,感兴趣的能够看一下 RN 文档中 Javascript Environment 里提到的支持的方法,须要时再来查询也能够。也能够看 Babel 出的 Learn ES2015 手册

这里有一个很不错的 GitHub 项目,帮助你经过交互性的例子来快速上手语法知识:React Native Express

6、UI 层

简单熟悉了 React 语法后,基本能正常阅读 RN 的示例代码了。

正式开发 App 的第一步固然就是写 UI 界面了,因为 RN 已经封装好了一套 JS 的 UI 组件,这些组件会自动在 Android/iOS 端调用对应的原生 UI 组件,所以咱们只须要熟悉这些 UI 组件的用法及属性、回调方法便可。

咱们能够在文档的 Components 看到很多组件,好比View, Text, Button, Image, Switch, 还有咱们用的最多的 ScrollView 和 ListView

在读文档时,咱们能够先经过一边写代码一边读文档的方式进行,RN 很是贴心,直接在 Web 里嵌入了模拟器,咱们只要修改编辑框里的代码,当即就能在右边的模拟器看到效果。这极大的下降了咱们的学习成本。


Text Component

另外,在学习一个组件时,咱们要区分哪一个属性是某个平台特有的。好比下面两个 Text 的属性:textBreakStrategy 只会在 Android 上生效,而 adjustsFontSizeToFit 只能够用在 iOS 上。


Platform Specific Properties

而后,若是你但愿在 Android 和 iOS 里显示不一样的内容怎么办呢?RN 里有一节是Platform Specific Code,能够有以下几种形式来进行区分:

if (Platform.OS === 'ios') { // stuff for ios } else { // stuff for android }

除此以外,UI 组件的用法学习就很相似常规的 Html 标签了,只要知道其使用方式便可,甚至须要用的时候再来查文档也行。

7、网络请求层

学完上面的咱们已经可以写出 UI 界面了,并且这套界面已经可以在不一样平台上转化成各自平台的 Native UI 了。而后,咱们就须要去网络层请求真实数据了。

RN 里提供了 Fetch API 来进行实现。举个例子,你想要经过 GET 方法去请求数据并转化成 JSON,能够经过以下代码实现:

fetch('https://facebook.github.io/react-native/movies.json') .then((response) => response.json()) .then((responseJson) => { return responseJson.movies; }) .catch((error) => { console.error(error); });

熟悉 Reactive 编程的伙伴应该对这样的语法不陌生,好比 Android 上的 RxJava; iOS 上的 RxSwift;Web 上的 RxJS。上面 function 的功能就是:请求网址 https://facebook.github.io/react-native/movies.json,把返回的 Response 转化成 JSON object,取出 JSON object 里的 movies 字段。同时,若是发生 error 会被 catch 住。

固然,上面是最基本的 GET 请求,Fetch API 还支持自定义 Headers,更换 Method,添加 Body 等。

fetch('https://mywebsite.com/endpoint/', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ firstParam: 'yourValue', secondParam: 'yourOtherValue', }) })

上面构建了一个基本的 POST 请求,添加了本身的 Headers:AcceptContent-Type,添加了 Body。

所以看下来,RN 里的网络请求不只具有了 Reactive 编程的简洁,也能自定义常规的 Http 请求,写法简单。

除了 Fetch API 以外,RN 还内置了 XMLHttpRequest API(俗称 AJAX),并且支持TCP 全双工通讯方式 WebSocket

8、Debugging 调试

调试是不少程序员很是关注的一个环节,由于 RN 是用 JS 写完后到 Native 解释成 Native 方法来执行的,所以若是能快速调试 JS 代码是很是重要的一环。

最开始 RN 的调试功能比较弱,不过如今的 Debugging 功能在我看来仍是很不错的。通常来说能够有如下几个调试方式:

1. In-App 报错

RN 里默认集成了 In-App 的错误提示方式,即在 App 运行过程当中会弹出全屏的报错信息呈现给你,而你也能够经过阅读具体的错误信息快速找到错误缘由。经过点击这个错误信息里的某一行,会当即自动打开对应的代码。


In-App Error
2. Console.log

在开发 Client 时,咱们通常都会用 Log.log() 来打印一些运行时变量的值,而后实时查看打印出来的 log 来调试,在 RN 也同样,你只要在 JS 里写一句 console.log('this is log data'),就会自动在 Client 的常规 log 里能看到,好比 Android 的 adb logcat 里就会自动打印出'this is log data'一行。

3. 大杀器:Chrome 逐行调试

这个杀器的最牛逼之处就是能够像 Client 同样,逐行调试代码!

咱们来看下面一张图。从左往右。先是文件目录,咱们选中了 index.js 文件夹,而后第二个 Tab,是 index.js 的内容。这里关键的是我能够直接选中某一行代码设断点。当 Client 运行到这一行时,就会在第三个 Tab 里打印出运行时环境及变量。咱们能够看到 props 里就有咱们传进去的变量值。


Chrome Debug

有了以上几种调试方式,咱们几乎能够和常规的 Native 开发同样来调试 RN 代码了,不得不说 RN Team 确实牛 x 啊!

9、从 JS 调用 Native 方法或显示自定义 Native View

这又是另外一个牛 x 之处啊。

不少人以为 RN 限制太多,只能支持有限的 View 组件和有限的方法,难以发挥 Client 的最大性能。简单点说,在 Client 能够绘制复杂的 View,能够调用高性能 C++ 等底层代码,但 RN 却作不到。

因而,RN 里提出了 Native Modules 和 Native UI Component 两种技术。

Native Modules:JS 里直接调用 Native(Java/Swift) 方法

所谓 Native Modules,就是本身在 Client 写好了某些方法,因为某些缘由这些方法不太方便或者没法搬到 RN 里面,那么,咱们能够在 Client 把这些方法暴露出来给 RN,而后在 JS 里能够像 import 普通的 module 同样把这些 Native Modules 引入进去,直接调用。

具体的实现方法能够参考文档 iOS Native Modules 和 Android Native Modules

Native UI Component:JS 里直接调用自定义的 Native View

不少时候咱们在写 Client 时,为了实现 Designer 天马行空的设计,经常须要自定义 View,即本身绘制某些系统并不提供的特定 UI。可想而知,这些 View 确定不会出如今 RN 的 UI Component 里。

那么,咱们就须要首先在 Native 层本身写好一个自定义 View,而后利用Native UI Component 技术把这个 View 及其中某些 public 方法暴露给 RN,那么 RN 就能直接 import 进来并显示了。

具体的实现方法能够参考文档 iOS Native UI Component 和 Android Native UI Component

若是读过文档不是很理解的小伙伴能够留言,我再 post 一些 demo 代码上来

10、React Native 适合你吗?

这里借鉴下前段时间旧金山的 React Native 会议上的一些优劣总结给读者以参考。固然不必定对,仅供参考。

RN 的优势:

  • 跨平台
  • 原生的用户体验
  • 开发者体验好
  • 动态更新代码逻辑
  • 社区强大
  • 有个好爹

RN 的缺点:

  • 不够成熟
  • 不够稳定
  • 生态系统在搭建中
  • 优质的 App 须要时间打磨
  • 偶尔须要写 Native 代码(也就是 JS + Swift + Java)

适合下面这些人/公司:

  • 你对 JS/React 有必定了解
  • Web 开发人员比 Mobile 开发人员多
  • 有意愿投资精力给 RN
  • App 设计不是特别区分 Android 和 iOS
  • 但愿热更新

下面这些人要稍微考虑下:

  • 彻底不了解 JS/React
  • 已经有现成的 Android/iOS team
  • App 设计严格遵照 Android、iOS各自设计规范
  • 不想要投入时间/金钱给 RN

11、为何要写这篇文章

几个月前我对 React Native 也很是不看好,固然如今也没有说很是看好。或者说,写这篇文章毫无为 React Native 布道之意。

接触 React Native 主要是由于业务须要,PM 但愿可以随时改动某块变化较大的模块,常规的开发提交流程每每须要较长的时间,而热修复技术自己并未获得 Google 和 Apple 的官方承认,也就是随时可能因破坏生态安全之名被取缔。

所以才考虑去了解 Hybrid 开发和 JS Native 开发模式,在了解过程当中,又因为性能差、用户体验很差而放弃 Hybrid,因为社区不完善、Bug 较多等缘由放弃 Weex,最终才选择了 React Native,开始学习 React、JSX等语法。

目前使用下来对 React Native 的一些我的感觉:

  1. 学习门槛并无开始想象那么高。大概只花了两三天时间就熟悉了 Javascript、React 框架、JSX语法,而后就开始着手业务开发。
  2. 对 Android App 的影响。React Native 会给 Android 端带来 6MB 左右的 size 增幅,不过在采用了 split apk 后就只有 1MB 左右增幅。
  3. Debug 功能比较完善,至少不用担忧发生问题后不知从哪下手。
  4. 性能还行。最初担忧的是 React Native 性能很差,但本身上手后,并无明显感受到很明显的 React Native 对 App 性能的负面影响,不管是 iOS 仍是 Android,固然,这一点还在继续考察中。
  5. 动态部署真的很不错。之前每次写好代码都要花很多时间来编译运行,而如今只要写一份代码,就能够同时在 Android 和 iOS 实时更新了,这无疑节省了生命。
  6. 有待完善。固然,React Native 中确实还存在着很多问题,生态系统也还不够完善。不过我相信,这只是时间问题。

关于React Native一直以来都有不少争议。

不过我想说的是,React Native 所表明的跨平台、动态更新技术已经引发了全世界开发者关注,并且这种技术势必会是将来的需求和潮流。React Native 不必定会成功,但至少目前 React Native 已是这一领域的领跑者。

而写这篇文章的目的,就是但愿告诉更多开发者,React Native 并不完美,但值得一试。

谢谢。

相关文章
相关标签/搜索