®
世界顶尖人才,点播 ®

Toptal, LLC版权所有

\n \n\n\n\n

这个例子意味着我们几乎可以使用任何我们想要的东西, 比如使用像NPM或Bower这样的包管理器, using a transpiler such as Babel, CoffeeScript or TypeScript, a bundler like Webpack or Rollup, or something else entirely. 没关系,只要结果是一个 index.html 加载我们需要的所有JavaScript和样式表的文件.

\n\n

顾名思义,React Native构建在React之上. 重要的是要理解React Native中的React部分是它的核心功能之一. 如果你不喜欢React的声明性, including JSX, its componentization, and data flow, 很有可能你不会对React Native感到满意. 而React Native会让你立刻感到熟悉 React developers乍一看,有一些不同要记住. React Native不需要任何HTML或CSS. 相反,该技术侧重于JavaScript端. 作为CSS的替代方案,样式是内联编写的,而Flexbox是默认的样式模型.

\n\n

最基本的React Native应用程序看起来类似于这个例子:

\n\n
//导入React模块进行JSX转换\nimport { React } from 'react';\n//导入React Native的组件\nimport {\n  View,\n  Text,\n  AppRegistry,\n  TouchableOpacity,\n} from 'react-native';\n\n// Create an App component\nconst App = () => {\n  // Define our press handler\n  const onPress = () => alert('Hello there!');\n  \n  //组合我们要渲染的组件\n  return (\n    \n      \n        Tap me!\n      \n    \n  );\n};\n\n//注册' App '组件作为主入口点\nAppRegistry.registerComponent('App', () => App);\n
\n\n

React Native有自己的打包器. 它将所有JavaScript文件捆绑到一个大文件中, 然后由JavaScriptCore消费和执行, Apple’s JavaScript engine. JavaScriptCore正在iOS和Android上使用, 而ChakraCore正在为React Native UWP应用程序提供支持. By default, React Native使用JavaScript转译器Babel, 允许我们使用ECMAScript 2015+ (ECMAScript 6)语法. 虽然没有必要使用ECMAScript 2015+语法, it is definitely encouraged, 因为所有的官方示例和第三方模块都支持它. 因为React Native负责打包和编译过程, 我们的应用程序代码和第三方模块可以利用这些特性,而不需要为自己配置工具.

\n\n

To sum up, React Native是一种以React为中心的移动开发方法, 而Cordova允许我们在WebView shell中捆绑web技术.

\n\n

Native Look and Feel

\n\n

对用户来说很重要的一件事是拥有应用程序的原生外观和感觉. 因为Cordova应用通常是简单的web应用, 有一些事情一开始可能会感到奇怪. 问题可能包括缺少点击区域的视觉反馈, 滚动的感觉不像原生应用那样流畅, 在点击事件上有300毫秒的延迟. 虽然所有这些问题都有解决方案, 我们应该记住,如果我们希望我们的Cordova应用程序感觉尽可能接近本机应用程序,我们可能需要付出一些额外的努力. 在Cordova,我们无法访问任何本地控件. 如果我们想有一个本地的外观和感觉, 我们剩下两个选择:要么重新创建本机控件, 例如按钮和输入元素, with HTML and CSS, 或者实现直接访问这些本地控件的本地模块. 我们可以自己完成,也可以使用第三方库,比如 Ionic or Onsen UI. 注意,重要的是要使它们与操作系统更新保持同步. Sometimes, 移动操作系统的外观得到了提升, 就像iOS 7发布时一样. 拥有一款无法适应的应用会让用户失去体验. 我们也可以求助于包括Cordova插件,将我们连接到本地的东西. 最完整的原生控件之一是 Microsoft’s Ace library.

\n\n

With React Native, on the other hand, 我们可以访问本地控件和开箱即用的交互. Components such as Text, TextInput or Slider map to its native counterparts. 虽然有些组件可用于所有平台, 其他组件仅在特定平台上工作. 我们希望我们的应用程序有一个本地的外观和感觉, 我们越是需要使用只在这个特定平台上可用的组件,那么我们的代码库就会出现更多的分歧. 心灵触摸交互和手势也是React Native的一部分.

\n\n

Comparing Performance

\n\n

由于Cordova只有一个WebView可以使用,我们受到了WebView的限制. For example, following its 4.0版本之后,Android终于开始使用(更快的)Chrome引擎作为默认的WebView. While with iOS, 长期以来,在默认WebView引擎中运行的应用程序比在Safari移动浏览器中运行的应用程序要慢得多. Furthermore, 因为JavaScript是单线程的, 如果应用程序代码中包含太多内容,我们可能会遇到问题. 这些限制导致了缓慢的动画, 我们的应用程序可能不会像我们希望的那样响应. 虽然我们可以在这里和那里使用一些技巧, in the end, 我们受到移动浏览器的限制.

\n\n

React Native使用多个线程,因此渲染UI元素在它们自己的线程中运行. 因为React组件链接到本地视图, JavaScript在React Native中没有做繁重的工作.

\n\n

Developer Workflow

\n\n

Cordova提供了一个命令行实用程序来创建新的项目模板, 在模拟器中启动应用程序,并在生产模式下为实际设备构建应用程序. Most of the time, 我们正在桌面浏览器上开发这个应用程序,以后可能会捆绑成一个移动应用程序. 有了Cordova提供的自由,我们需要自己处理开发工作流. 如果我们想要在设备上实时重新加载,我们需要自己实现它. 为了调试Cordova应用程序,我们采用与调试网站相同的原则. 以iOS为例,我们可以通过USB连接移动设备,打开Safari及其开发工具.

\n\n

React Native提供了类似的命令行界面,并提供了web开发人员熟悉的开发工作流. 我们从盒子里得到实时装填. 一旦我们改变了一个React组件,我们的应用程序就会重新加载我们所做的改变. 最令人兴奋的特性之一是热模块替换, 哪些部分会重新加载我们在组件中所做的更改, 而不改变应用程序的状态. 我们甚至可以连接到一个实际的设备,看看我们的改变是否像我们期望的那样在一个真实的设备上工作. 我们的React Native应用程序可以用Chrome for Desktop远程调试. Error handling is obvious in React Native; if we run into an error, 我们的应用程序显示一个红色背景, and the stack trace is shown. 多亏了源地图,我们可以看到错误的确切位置. 当我们点击它时,我们选择的编辑器会在代码的精确位置打开.

\n\n

可扩展性和对本地特性的访问

\n\n

从JavaScript的角度来看, 我们可以自由使用任何JavaScript库, including packages from NPM. However, 因为React Native不是浏览器环境, 我们可能会发现很难使用依赖于DOM的代码. React Native支持CommonJS和ES2015模块, 因此,任何使用这些格式的库都很容易集成.

\n\n

Cordova和React Native都有能力创建和使用连接到本地的插件. Cordova提供了一个低级API来创建我们自己的API, which give us a lot of control, 但是会导致使用更多的原生和JavaScript样板.

\n\n

假设我们要用Objective-C编写一个Cordova iOS插件, 它可能看起来像下一个代码片段. 我们的插件将只记录输入参数.

\n\n
#import \n\n//创建一个继承自CDVPlugin的类\n@interface Log : CDVPlugin\n- (void)日志:(CDVInvokedUrlCommand *)命令;\n@end\n\n//我们刚刚定义的类的实际实现\n@implementation Log\n\n- (void)日志:(CDVInvokedUrlCommand *)命令\n{\n    CDVPluginResult* pluginResult = nil;\n    \n    //获取所有参数并取第一个参数\n    NSString* echo = [command.arguments objectAtIndex:0];\n\n    //检查参数的有效性\n    if (echo != nil && [echo length] > 0) {\n        //我们只是使用本地日志方法打印参数\n        NSLog(echo);\n      \n        //让我们为插件创建一个结果\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];\n    }\n\n    //发送一个带有插件结果的信号\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:命令.callbackId];\n}\n\n@end\n
\n\n

为了使用该模块,这段JavaScript代码将会有所帮助:

\n\n
window.log = function(str, callback) {\n    cordova.exec(callback, function(err) {\n        callback('Nothing to echo.');\n    }, \"Log\", \"log\", [str]);\n};\n
\n\n

要使用插件,我们只需要调用 log function:

\n\n
window.log('Hello native!');\n
\n\n

React Native, on the other hand, follows a different philosophy; it automatically maps JavaScript types to its native counterparts when writing plugins, 这使得它更容易连接本地代码与JavaScript. 让我们来看看用React native创建原生模块所必需的一段代码:

\n\n
#import \"RCTBridgeModule.h\"\n\n@interface Log : NSObject \n@end\n\n@implementation Log\n\nRCT_EXPORT_MODULE();\n\n//这使得这个方法可用.Log.log\nRCT_EXPORT_METHOD(日志:(NSString *)消息)\n{\n  NSLog(message);\n}\n@end\n
\n\n

React Native通过调用为我们绑定模块 RCT_EXPORT_MODULE and RCT_EXPORT_METHOD. We can now access it with NativeModules.Log.log as so:

\n\n
import { React } from 'react';\nimport {\n  View,\n  Text,\n  AppRegistry,\n  NativeModules\n  TouchableOpacity,\n} from 'react-native';\n\n// Create an App component\nconst App = () => {\n  //点击文本后使用我们的模块记录日志\n  const onPress = () => NativeModules.Log.log('Hello there');\n  \n  return (\n    \n      \n        Tap me!\n      \n    \n  );\n};\n\n//注册' App '组件作为主入口点\nAppRegistry.registerComponent('App', () => App);\n
\n\n

虽然我们只仔细研究了使用Objective-C在iOS中创建模块, 同样的原则也适用于使用Java为Android创建模块.

\n\n

我们需要在每个平台的项目文件中链接本地插件. With iOS, for example, 这意味着我们必须将编译后的本机部分与我们的应用程序链接起来,并添加相应的头文件. 这可能是一个漫长的过程,特别是如果有很多本地模块. 幸运的是,通过使用名为 rnpm 它已经成为React Native本身的一部分.

\n\n

结论:React Native或Cordova?

\n\n

React Native和Cordova有不同的目的,因此迎合了不同的需求. 因此,很难说一种技术在所有学科中都比另一种技术好.

\n\n

By using Cordova, 您可以快速地将现有的单页应用程序转换为针对不同平台的移动应用程序, 以互动为代价不一定对自己的特定平台有原生的感觉.

\n\n

With React Native, 应用程序具有更原生的外观和感觉,但代价是为某些目标平台重新实现代码片段. 如果你已经涉足React,并且对开发移动应用程序感兴趣, React Native感觉像是一个自然的扩展.

\n\n
\nRelated: 冷潜入React Native:初学者教程\n
\n","as":"div","isContentFit":true,"sharingWidget":{"url":"http://ped.hebhgkq.com/app/comparing-react-native-to-cordova","title":"Comparing React Native to Cordova","text":null,"providers":["linkedin","twitter","facebook"],"gaCategory":null,"domain":{"name":"developers","title":"Engineering","vertical":{"name":"developers","title":"Developers","publicUrl":"http://ped.hebhgkq.com/developers"},"publicUrl":"http://ped.hebhgkq.com/developers/blog"},"hashtags":"Mobile,ReactNative,Cordova,HybridApps"}}