跟我学用React Native构建原生应用(一)

本文案例、代码及主要内容基于知乎前端专栏翻译的文章《深入浅出React Native:使用JavaScript构建原生应用》《Introducing React Native: Building Apps with JavaScript》而写。

在原文的基础上做了一些校对,并增加了android得环境安装和调试的内容。

由我书写的注释将会显示左边这个紫色竖线(#523f6d),而原文的注释为蓝色的(#559bce)。

内容传送门

一、《深入浅出R跟我学用React Native构建原生应用(一)
二、《深入浅出R跟我学用React Native构建原生应用(二)
三、《深入浅出R跟我学用React Native构建原生应用(三)
四、《深入浅出R跟我学用React Native构建原生应用(四)
五、《深入浅出R跟我学用React Native构建原生应用(五)
六、《深入浅出R跟我学用React Native构建原生应用(六)

数月前,Facebook 对外宣布了正在开发的 React Native 框架,这个框架允许你使用 JavaScript 开发原生的 iOS 应用——就在今天,Beta 版的仓库释出了!基于 PhoneGap 使用 JavaScript 和 HTML5 开发 iOS 应用已经有好几年了,那 React Native 有什么牛的?React Native 真的很牛,让大家兴奋异常的主要原因有两点:

  1. 可以基于 React Native使用 JavaScript 编写应用逻辑,UI 则可以保持全是原生的。这样的话就没有必要就 HTML5 的 UI 做出常见的妥协;
  2. React 引入了一种与众不同的、略显激进但具备高可用性的方案来构建用户界面。长话短说,应用的 UI 简单通过一个基于应用目前状态的函数来表达。

React Native 的关键就是,以把 React 编程模式的能力带到移动开发来作为主要目标。它的目标不是跨平台一次编写到处执行,而是一次学习跨平台开发。这个是一个非常大的区别。这篇教程只介绍 iOS 平台,不过你一旦掌握了相关的概念,就可以应用到 Android 平台,快速构建 Android 应用。

如果之前只用过 Objective-C 或者 Swift 写应用的话,你很可能不会对使用 JavaScript 来编写应用的愿景感到兴奋。尽管如此,作为一个 Swift 开发者来说,上面提到的第二点应该可以激起你的兴趣!

你通过 Swift,毫无疑问学习到了新的更多有效的编码方法和技巧,鼓励转换和不变性。然而,构建 UI 的方式还是和使用 Objective-C 的方式一致。仍然以 UIKit 为基础,独断专横。

通过像 virtual DOM 和 reconciliation 这些有趣的概念,React 将函数式编程直接带到了 UI 层。

这篇教程将带着你一路构建一个 UK 房产搜索应用:

062e83eb739070f18971e3d7a3f473ff_b

如果你之前一点 JavaScript 都没写过,别担心。这篇教程带着你进行一步一步进行编码。React 使用 CSS 属性来定义样式,一般比较容易读也比较容易理解。但是如果你想了解更多的话,可以去看看 Mozilla Developer Network reference,很不错的。想要学习更多,继续往下读!

准备工作

React Native 框架托管在 GitHub 上。你可以通过两种方式获取到它:使用 git 克隆仓库,或者下载一个 zip 压缩包文件。如果你的机器上已经安装了 React Native,在着手编码前还有其他几个因素需要考虑。

  • React Native 借助 Node.js,即 JavaScript 运行时来创建 JavaScript 代码。如果你已经安装了 Node.js,那就可以上手了。

首先,使用 Homebrew 官网提供的指引安装 Homebrew,然后在终端执行以下命令:

brew install node

接下来,使用 homebrew 安装 watchman,一个来自Facebook 的观察程序:

brew install watchman

通过配置 watchman,React 实现了在代码发生变化时,完成相关的重建的功能。就像在使用 Xcode 时,每次保存文件都会进行一次创建。

接下来使用 `npm` 安装 React Native CLI 工具:

npm install -g react-native-cli

如果是用mac开发,使用npm遇到问题了,可以看下《MAC安装NPM插件的权限问题》这篇文章。后面还附带一个淘宝镜像的使用方法。

这使用 Node 包管理器抓取 CLI 工具,并且全局安装;`npm` 在功能上与 CocoaPods 或者 Carthage 类似。

浏览到你想要创建 React Native 应用的文件夹下,使用 CLI 工具构建项目:

react-native init PropertyFinder

现在,已经创建了一个初始项目,包含了创建和运行一个 React Native 应用所需的一切。

如果仔细观察了创建的文件夹和文件,你会发现一个 node_modules 文件夹,包含了 React Native 框架。你也会发现一个 index.ios.js 文件,这是 CLI 工具创建的一个空壳应用。最后,会出现一个 Xcode 项目文件和一个 iOS 文件夹,包含了少量的代码用来引入 bootstrap 到你的项目中。

打开 Xcode 项目文件,然后创建并运行。模拟器将会启动并且展示下面的问候语:

062e83eb739070f18971e3d7a3f473ff_b (1)
你可以能发现,有一个终端窗口弹出,输出了下面的信息:

$ npm start

> react-native@0.1.0 start /Users/colineberhardt/Projects/react-native
> ./packager/packager.sh

 ===============================================================
 |  Running packager on port 8081.       
 |  Keep this packager running while developing on any JS         
 |  projects. Feel free to close this tab and run your own      
 |  packager instance if you prefer.                              
 |                                                              
 |     https://github.com/facebook/react-native                 
 |                                                              
 ===============================================================

    React packager ready.

这就是 React Native 包,在 node 下运行。一会儿你就会知道它是用来干什么的。

不要关闭终端窗口;就然它在后台运行。如果你不小心关了,只需要停下来使用 Xcode 重新运行项目。

注意:在进入编码工作之前,还有最后一件事 —— 在这个教程中,你需要编写大量的 JavaScript 代码,Xcode 并非是最好的工具! Sublime Text,一个价格合理且应用广泛的编辑器。不过,atombrackets 或者其他轻量的编辑器都能胜任这份工作。

我使用的时webStrom10,这个版本的webStrom已经支持JSX的语法,还是比较方便的。

React Native 你好

在开始“搜房App”之前,先来个简单的 Hello World App 热热身。在这一节里,你将会使用到一些组件。

在你钟爱的编辑其中打开 index.ios.js,删除当前的内容,因为你要从头构建你自己的应用。然后在文件顶部增加下面这样一行::

'use strict';

这行代码是用于开启 Strict Mode,Strict mode的错误处理可以有所提高,JavaScript的一些语言缺陷也可以避免。简而言之就是,JavaScript在这种模式下工作地更好!

注意:想要研究一下 Strict Mode 的朋友,我会推荐你阅读 Jon Resig 的文章:“ECMAScript 5 Strict Mode, JSON, and More”

然后,加上这一行:

var React = require('react-native');

这句代码是将 react-native 模块加载进来,并将它赋值给变量 React 的。React Native 使用同 Node.js 相同的模块加载方式:require,这个概念可以等同于 Swift 中的“链接库”或者“导入库”。

注意:想要了解更多关于 JavaScript 模块的知识,我推荐阅读 Addy Osmani 写的这篇文章

在 require 语句的下面,加上这一段:

var styles = React.StyleSheet.create({
  text: {
    color: 'black',
    backgroundColor: 'white',
    fontSize: 30,
    margin: 80
  }
});

以上代码定义了一段应用在 “Hello World” 文本上的样式。如果你曾接触过Web开发,那你很可能已经发现了:React Native 使用的是 CSS 来定义应用界面的样式。

现在我们来关注应用本身吧!依然是在相同的文件下,将以下代码添加到样式代码的下面:

class PropertyFinderApp extends React.Component {
  render() {
    return React.createElement(React.Text, {style: styles.text}, "Hello World!");
  }
}

是的,奏是 JavaScript class!

类 (class) 是在ES6中被引入的,纵然JavaScript一直在进步,但Web开发者受困于兼容浏览器的状况中,不能怎么使用JS的新特性。React Native运行在JavaScriptCore中是,也就是说,你可以使用JS的新特性啦,完全不用担心兼容什么的呢。

注意:如果你是一名 Web 开发者,我百分百鼓励你要使用现代的JavaScript,然后使用像 Babel 这样的工具生成兼容性的 JavaScript,用于支持兼容性不好的老浏览器。

注意:截止到我整理这套教程的时间,react-native初始化的代码样例还是ES5的,这并不影响你的使用,如果有兴趣你可以去了解一下ES5ES6对这部分操作的区别,以帮助你更好地区分和理解。

PropertyFinderApp 继承了 React.Component(React UI的基础模块)。组件包含着不可变的属性,可变的状态变量以及暴露给渲染用的方法。这会你做的应用比较简单,只用一个渲染方法就可以啦。

React Native 组件并不是 UIKit 类,它们只能说是在某种程度上等同。框架只是将 React 组件树转化成为原生的UI。

最后一步啦,将这一行加在文件末尾:

React.AppRegistry.registerComponent('PropertyFinder', function() { return PropertyFinderApp });

AppRegistry 定义了App的入口,并提供了根组件。

保存 PropertyFinderApp.js,回到Xcode中。确保 PropertyFinder 规划(scheme)已经勾选了,并设置了相应的 iPhone 模拟器,然后生成并运行你的项目。几秒之后,你应该就可以看到 “Hello World” 应用正在运行了:

80b700261430c5da1da10c9034afbc6b_b

这个JavaScript应用运行在模拟器上,使用的是原生UI,没有任何内嵌的浏览器哦!还不相信这是真的?:] 那打开你的 Xcode,选择 Debug\View Debugging\Capture View Hierarchy,你看 native view hierarchy 中都没有 UIWebView,就只有一个原生的view!

a54cf6d88da1ca1a2d32bc8e47806698_b
你一定很好奇其中的原理吧,那就在 Xcode 中打开 AppDelegate.m,接着找到 application:didFinishLaunchingWithOptions:这个方法构建了 RCTRootView 用于加载 JavaScript 应用以及渲染最后的视图的。

当应用开始运行的时候,RCTRootView将会从以下的URL中加载应用:

http://localhost:8081/index.ios.bundle

重新调用了你在运行这个App时打开的终端窗口,它开启了一个 packager 和 server 来处理上面的请求。

在 Safari 中打开那个 URL;你将会看到这个 App 的 JavaScript 代码。你也可以在 React Native 框架中找到你的 “Hello World” 代码。

当你的App开始运行了以后,这段代码将会被加载进来,然后 JavaScriptCore 框架将会执行它。在 Hello World 的例子里,它将会加载 PropertyFinderApp 组件,然后构建出原生的 UIKit 视图。关于这部分的内容,后文里会再详细解释的。

发表回复