®
The World’s Top Talent, On Demand ®

Copyright 2010 - 2024 Toptal, LLC

\n \n\n\n\n

这个例子意味着我们几乎可以使用任何我们想要的东西, such as using a package manager like NPM or Bower, using a transpiler such as Babel, CoffeeScript or TypeScript, a bundler like Webpack or Rollup, or something else entirely. It doesn’t matter, as long as the result is an index.html file that loads all the JavaScript and stylesheets we need.

\n\n

React Native, as the name implies, builds upon React. 重要的是要理解React Native中的React部分是它的核心功能之一. If you are not a fan of React’s declarative nature, including JSX, its componentization, and data flow, 很有可能你不会对React Native感到满意. While React Native instantly feels familiar to React developers, at first sight, there are some differences to remember. With React Native we don’t have any HTML or CSS. Instead, this technology is focused on the JavaScript side. 作为CSS的替代方案,样式是内联编写的,而Flexbox是默认的样式模型.

\n\n

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

\n\n
// Import the React module for JSX conversion\nimport { React } from 'react';\n// Import React Native's components\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  // Compose the components we are going to render\n  return (\n    \n      \n        Tap me!\n      \n    \n  );\n};\n\n// Registers the `App` component as our main entry point\nAppRegistry.registerComponent('App', () => App);\n
\n\n

React Native has its own packager. It bundles all the JavaScript files into one giant file, which is then consumed and executed by JavaScriptCore, Apple’s JavaScript engine. JavaScriptCore is being used on iOS and Android, while ChakraCore is powering React Native UWP applications. By default, React Native uses the JavaScript transpiler Babel, allowing us to use ECMAScript 2015+ (ECMAScript 6) syntax. While it’s not necessary to use ECMAScript 2015+ syntax, 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应用, there are a few things that might feel strange at first. 问题可能包括缺少点击区域的视觉反馈, 滚动的感觉不像原生应用那样流畅, to there being a 300-millisecond delay on tap events. While there are solutions for all of these issues, 我们应该记住,如果我们希望我们的Cordova应用程序感觉尽可能接近本机应用程序,我们可能需要付出一些额外的努力. In Cordova, we don’t have access to any native controls. If we want to have a native look and feel, 我们剩下两个选择:要么重新创建本机控件, such as buttons and input elements, with HTML and CSS, 或者实现直接访问这些本地控件的本地模块. 我们可以自己完成,也可以使用第三方库,比如 Ionic or Onsen UI. 注意,重要的是要使它们与操作系统更新保持同步. Sometimes, the look of a mobile operating system gets a facelift, as happened when iOS 7 was introduced. 拥有一款无法适应的应用会让用户失去体验. 我们也可以求助于包括Cordova插件,将我们连接到本地的东西. One of the most complete native controls is 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. While some components are available for all platforms, other components only work on specific platforms. 我们希望我们的应用程序有一个本地的外观和感觉, 我们越是需要使用只在这个特定平台上可用的组件,那么我们的代码库就会出现更多的分歧. 心灵触摸交互和手势也是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, since JavaScript is single threaded, 如果应用程序代码中包含太多内容,我们可能会遇到问题. These limitations lead to sluggish animations, 我们的应用程序可能不会像我们希望的那样响应. 虽然我们可以在这里和那里使用一些技巧, in the end, we are bound by the mobile browser’s limits.

\n\n

React Native使用多个线程,因此渲染UI元素在它们自己的线程中运行. Because React components link to native views, JavaScript is not doing the heavy lifting in React Native.

\n\n

Developer Workflow

\n\n

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

\n\n

React Native提供了类似的命令行界面,并提供了web开发人员熟悉的开发工作流. We get live reloading out of the box. 一旦我们改变了一个React组件,我们的应用程序就会重新加载我们所做的改变. 最令人兴奋的特性之一是热模块替换, 哪些部分会重新加载我们在组件中所做的更改, without altering the application’s state. 我们甚至可以连接到一个实际的设备,看看我们的改变是否像我们期望的那样在一个真实的设备上工作. 我们的React Native应用程序可以用Chrome for Desktop远程调试. Error handling is obvious in React Native; if we run into an error, our application displays a red background, and the stack trace is shown. 多亏了源地图,我们可以看到错误的确切位置. 当我们点击它时,我们选择的编辑器会在代码的精确位置打开.

\n\n

Extensibility and Access to the Native Features

\n\n

From the JavaScript side of things, we are free to use any JavaScript library, including packages from NPM. However, because React Native is not a browser environment, 我们可能会发现很难使用依赖于DOM的代码. React Native embraces CommonJS and ES2015 modules, 因此,任何使用这些格式的库都很容易集成.

\n\n

Cordova和React Native都有能力创建和使用连接到本地的插件. Cordova provides a low-level API for creating our own, which give us a lot of control, 但是会导致使用更多的原生和JavaScript样板.

\n\n

假设我们要用Objective-C编写一个Cordova iOS插件, it might look like the next code snippet. Our plugin will just log the input parameter.

\n\n
#import \n\n// Create a class that inherits from CDVPlugin\n@interface Log : CDVPlugin\n- (void)log:(CDVInvokedUrlCommand*)command;\n@end\n\n// The actual implementation of the class we just defined\n@implementation Log\n\n- (void)log:(CDVInvokedUrlCommand*)command\n{\n    CDVPluginResult* pluginResult = nil;\n    \n    // We are getting all parameters and taking the first one\n    NSString* echo = [command.arguments objectAtIndex:0];\n\n    // We are checking for the validity of the parameters\n    if (echo != nil && [echo length] > 0) {\n        //我们只是使用本地日志方法打印参数\n        NSLog(echo);\n      \n        // Let's create a result for the plugin\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];\n    }\n\n    // Let's send a signal back with the plugin's result\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

To use the plugin, we just need to call the 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// This makes this method available NativeModules.Log.log\nRCT_EXPORT_METHOD(log:(NSString *)message)\n{\n  NSLog(message);\n}\n@end\n
\n\n

React Native binds the module for us with the calls 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  // Log with our module once we tap the text\n  const onPress = () => NativeModules.Log.log('Hello there');\n  \n  return (\n    \n      \n        Tap me!\n      \n    \n  );\n};\n\n// Registers the `App` component as our main entry point\nAppRegistry.registerComponent('App', () => App);\n
\n\n

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

\n\n

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

\n\n

Conclusion: React Native or Cordova?

\n\n

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

\n\n

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

\n\n

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

\n\n
\nRelated: Cold Dive into React Native: A Beginner's Tutorial\n
\n","as":"div","isContentFit":true,"sharingWidget":{"url":"http://dvdzi.yscfrp.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://dvdzi.yscfrp.com/developers"},"publicUrl":"http://dvdzi.yscfrp.com/developers/blog"},"hashtags":"Mobile,ReactNative,Cordova,HybridApps"}}