我們用Flutter重寫了一個React Native應用

2022-01-06 前端之巔

去年,我們推出了一個名為 Flat App 的 React Native 入門套件。這個套件包含了一個扁平風格的 UI 設計和適用於 iOS 和 Android 的 Redux 和 NativeBase 組件。Flat App 基本上算是一種界面設計風格,旨在減少對風格元素的使用。眾所周知,開發人員更喜歡扁平設計,因為它可以讓界面設計變得更簡單和高效。作為一項實驗,我們使用谷歌的 Flutter 成功地重寫了這個應用,結果真的很棒。

在這篇文章中,我將從語言棧、UI、樣式和其他方面對 Flutter 和 React Native 進行比較。同時,我還將討論在重寫 Flat App 過程中遇到的一些挑戰,以及我們是怎樣解決的。

Flutter 是一個由谷歌構建的平臺,幫助我們快速構建可以在 Android 和 iOS 平臺上運行的應用程式。

Flutter 與眾不同的地方是它有一個 C/C++ 層,但系統的大部分都是用 Dart 實現的,開發人員可以輕鬆地進行讀取、替換或移除。這為開發人員提供了靈活的系統控制。

React Native 是一個 JavaScript 庫,但 Flutter 卻是一個 SDK,它使用的是一門名為 Dart 的程式語言。

雖然 JavaScript 最初是為 Web 開發而生,但到了今天,JavaScript 生態系統已經變得如此龐大,以至於很多地方都能看到它的身影。

React Native 在運行時將動態 JavaScript 代碼編譯為原生視圖,其餘代碼則通過嵌在應用程式內部的虛擬機來運行。

Dart 是一門由谷歌開發的通用程式語言。它還可用於構建 Web、伺服器端、移動端和物聯網設備應用程式。

Dart 受到很多程式語言的影響,其中對它影響最大的是 Java。Java 程式設計師應該很容易看出這兩種語言之間的相似之處。

Dart 是一種面向對象的程式語言,支持抽象、封裝、繼承和多態等特性。

Dart 程序可以在以下兩種模式下運行:

Dart 示例:

int fib(int n) => (n > 2) ? (fib(n - 1) + fib(n - 2)) : 1;void main() {  print('fib(20) = ${fib(20)}');}

儘管 Dart 擁有強大的社區影響力,但仍然被其他主流語言(如 JavaScript)佔了上風,因此很少有開發者了解 Dart。

但這種情況正在發生改變。感謝 Flutter 發布了 Beta 1!在我撰寫這篇文章時,Flutter 的 GitHub 代碼庫(https://github.com/flutter/flutter)已經獲得了 18000 個 star!

Flutter 有一個函數反應式框架,主要是受 React 的啟發。雖然 Flutter 是用 Dart 編寫的,但它也借鑑了 React 的一些最好的特性,幫助開發人員構建出漂亮的跨平臺行動應用程式。

在 React Native 中,樣式是通過 JavaScript 來定義的。React Native 的所有核心組件都接受名為 style 的 prop。樣式名稱和值通常與 Web 中的 CSS 類似。唯一的區別是,在 React Native 中,名稱採用了駝峰的格式。因此,要定義背景顏色,需要將樣式命名為 backgroundColor,而不是 background-color。

如果我們使用 StyleSheet.create 在一個地方定義多個樣式,代碼就會變得更清晰。隨著應用程式變得越來越複雜,這種方式會非常有用。

樣式的差異在 Flutter 中比在 React Native 中表現得更為明顯。這個從下面給出的例子就可以看出來。

這是一段 React Native 代碼,用於定義字體樣式和其他文本屬性。

import React, { Component } from 'react';import { AppRegistry, StyleSheet, Text, View } from 'react-native';export default class LotsOfStyles extends Component {  render() {    return (      <View style={styles.greybox}>        <Text>Lorem Ipsum</Text>      </View>    );  }}const styles = StyleSheet.create({  greybox: {    backgroundColor: #e0e0e0,    width: 320px;    height: 240px;    font: 900 24px Georgia;  }})// skip this line if using Create React Native AppAppRegistry.registerComponent('AwesomeProject', () => LotsOfStyles);

如果我們想要在 Flutter 中實現同樣的樣式,那麼可以寫成:

var container = new Container( // grey box  child: new Text(    "Lorem ipsum",    style: new TextStyle(      fontSize: 24.0      fontWeight: FontWeight.w900,      fontFamily: "Georgia",    ),  ),  width: 320.0,  height: 240.0,  color: Colors.grey[300],);

React Native 應用程式的架構被稱為 Flux。Facebook 使用 Flux 構建客戶端 Web 應用程式。Flux 使用的是單向數據流。Flux 更像是一種模式,而不是一種正式的框架。任何人都可以輕鬆使用 Flux,而無需編寫大量新代碼。

單向數據流是 Flux 的主要概念。

Dispatcher、Store 和 View 是具有不同輸入和輸出的獨立節點。Action 是包含新數據和 type 屬性的簡單對象。View 可能會產生新的操作,並通過系統傳播,以便對用戶交互做出響應。

Flutter 有一個名為 Flutter Flux 的 Dart 庫。它是一種單向數據流,受到 RefluxJS 和 Facebook Flux 的啟發。

Flutter Flux 不受 Flutter 團隊的官方支持,只是一個實驗性的軟體包。

Flutter Flux 幾乎與 React/React Native 的實現是一樣的,只是使用 Flutter 替換了 React。

Flutter Flux 實現了單向數據流模式,由 Action、Store 和 StoreWatcher 組成。

Action 修改保存在 Store 中的數據。Store 的數據被修改時會觸發 View 進行重新渲染。

Flutter Widget 和其他交互源通過調用 Action 對用戶的輸入做出響應。

使用 React Native 就像使用不包含 CSS 框架的 HTML 一樣。

與 Flutter 版本的 Flat App 不同,在使用 React Native 時,我們必須使用第三方庫,因為 React Native 沒有自己的 UI 組件庫。

我們使用了 NativeBase 等組件,它是我們自己創建的開源 UI 組件庫。React Native Elements、React Native Material Design 和 Shoutem 是其他可以考慮使用的 UI 庫。

Flutter 提供了自己的 UI 組件,以及在 Android 和 iOS 平臺上渲染組件的引擎。其中大部分組件符合 Material Design 風格。

我們正在使用 Flutter 的內置組件來開發應用程式的 UI。這些組件稱為小部件。我們只需使用正確的小部件,並將正確的 prop 傳給小部件,就可以獲得我們想要的 UI。

Flutter 中的每個小部件都有它們自己的屬性定義,並且可以嵌套在其他小部件中。窗口小部件還可以調用父部件的屬性。

Flutter 版本的 Flat App 比 React Native 更好,因為它與原生代碼的交互最少。這也是為什麼 Flutter 版的 Flat App 的動畫會運行得更快。

在 React Native 中,我們也可以橋接原生模塊和使用原生 UI 組件。但這在 Flutter 中是不可能的,因為 Flutter 有自己的渲染引擎。

這實際上也是 Flutter 尚未支持谷歌地圖的原因。

以下是 Flutter Widget 的幾個示例:

Drawer 是一種 Material Design 面板,可從 Scaffold 邊緣水平滑動出來,上面顯示應用程式的導航連結。下面分別是 Flutter 版 Flat App 的 Drawer 的代碼和 React Native 版的代碼(SideBar):

Inkwell 定義了一個 Material 矩形區域,可對觸摸做出響應。我們使用這個小部件創建漣漪效果,當用戶觸摸這個區域時就會出現波紋效果。

在 React Native 中,我們不需要創建一個全新的組件來實現這種漣漪效果。React Native 的 TouchableOpacity 已默認具有這樣的效果。

顧名思義,GestureDetector 是一個用於檢測手勢的小部件。GestureDetector 會嘗試識別與非空回調相對應的手勢。

如果這個小部件有子部件,就會根據子部件調整大小。如果沒有子部件,就會根據父部件調整大小。

如下面的代碼所示,GestureDetector 小部件將根據 Container 小部件調整大小。

GestureDetector 相當於 React Native 中的 TouchableOpacity。因此,我們不需要為它創建新的部件。

DefaultTabController 是默認的 TabController 小部件,在沒有明確指定小部件時會用到。

DefaultTabController 用於與 TabBar 或 TabBarView 共享 TabController。我們使用這個小部件與 TabBar 共享 TabController。

當不方便共享顯式創建的 TabController 時就可以使用這個小部件,因為 TabBar 小部件是由無狀態父部件或不同的小部件創建的。

在 React Native 版的 Flat App 中,我們使用 Tab Navigator 執行相同的操作。

React Native 背後有一個龐大的社區在支持。

這也是為什麼 React Native 擁有比 Flutter 更多的第三方庫和插件。

在 React Native 版的 Flat App 中,我們使用了很多不同的第三方庫,例如 Calendar、Carousel 和 Modal。

我們將 Flutter 版的 Flat App 與 Firebase 集成在一起來實現登錄和註冊功能。

在 Flutter 中,我們需要為 iOS 和 Android 平臺添加單獨的文件。在每個文件中,我們需要添加與平臺規則相關的代碼。

與 Flutter 應用中使用 Firebase 不是件簡單的事。請查看谷歌提供的演示(https://codelabs.developers.google.com/codelabs/flutter-firebase/),了解如何將 Firebase 添加到 Flutter 應用中。

為 Flutter 構建新的插件也很容易,幾乎每隔一天就會出現新的 Flutter 插件。

React Native 是由 Facebook 和 Instagram 的工程師於 2015 年創建的。從那時起,他們的十幾名工程師一直在全職開發 React Native,他們精益求精,希望幫助用戶解決他們面臨的所有問題。

不過,社區中也有很多人為這個項目做出了重要貢獻並解決了很多問題。

你通常可以在 React Native 文檔和指南中找到大多數問題的解決方案,或者可以在 StackOverflow 和 GitHub 上與其他 React Native 開發人員取得聯繫,你可以在上面展示你的項目或向其他開發人員尋求指導。

如果你想成為貢獻者,請先閱讀貢獻者指南和路線圖,以便了解其他人正在開展的工作。你還可以查看由社區提出的最常用的功能清單。

Flutter 的文檔非常全面,可以幫助你入門 Flutter 開發。

Flutter Gallery(https://github.com/flutter/flutter/tree/master/examples/flutter_gallery)展示了所有可用的 Flutter 組件。我們也可以參看 Flutter 的 GitHub 代碼庫,了解它的實現。

Flutter 社區並不像 React Native 那樣強大。但是,谷歌 Flutter 團隊為此提供了非常好的支持。他們提供了很多方式來收集我們的問題,並在合理的時間內解決這些問題。

雖然 React Native 是一個單獨的代碼庫(JavaScript),但它的 View 組件在 iOS 上的行為與在 Android 上的行為不一樣。

儘管 React Native 的廣大社區可以為我們提供很多不同的插件和庫,但也可能導致與現有項目的其他插件發生衝突。

如果你有使用 JSX 的經驗,那麼編寫 Flutter 的 UI 代碼對你來說可能有點乏味。隨著 UI 變得越來越複雜,代碼可讀性也會隨之下降。

一種解決方案是將代碼重構為方法和小部件。我們目前正在嘗試這種方法,看看它是否會讓 build() 方法變得更容易閱讀。

在 Flutter 中,沒有必要將代碼都放在 build() 方法中。相反,你可以把它分解成更小的小部件!

與 React Native 相比,Flutter 的資源確實有點匱乏。其中一個重要的原因是 Flutter 存在的時間沒有 React Native 那麼長。但自從 Beta 版本發布以來,Flutter 的資源有了巨大的增長。

Flutter 的一個主要好處是它提供了內置的 UI 組件,因此我們不需要導入第三方 UI 庫。通過減少原生層和運行時環境之間的交互,Flutter 讓應用程式可以更平穩更快地運行。

Flutter 剛進入 Beta 階段,但已經有不少開發人員使用它構建應用程式。Flutter 還有很長的路要走。谷歌的 Flutter 團隊正在全力以赴,將 Flutter 帶給廣大開發者。

https://blog.geekyants.com/we-rebuilt-a-react-native-app-with-flutter-4160f0499a82

推薦極客時間《技術管理實戰 36 講》專欄,前百度最佳經理人劉建國為你解惑團隊 leader 的 36 個場景,傳授打造高效團隊的 13 種方法,分享十年管理的「戰地筆記」。

現在訂閱,立享限時福利:

福利一:限時優惠價¥45,原價¥68,8 月 25 日恢復原價

福利二:每邀請一位好友購買,你可獲得 12 元現金返現,好友可返 6 元。多邀多得,上不封頂,隨時提現(提現流程:極客時間 App - 我的 - 分享有賞)

點「閱讀原文」,免費試讀或訂閱!

相關焦點

  • 最火移動端跨平臺方案盤點:React Native、weex、Flutter
    1、前言跨平臺一直是老生常談的話題,cordova、ionic、react-native、weex、kotlin-native、flutter等跨平臺框架的百花齊放,頗有一股推倒原生開發者的勢頭。為什麼我們需要跨平臺開發?
  • ReactNative從零到完整項目-嵌入到安卓原生應用
    在Android項目根目錄中使用npm來安裝`react-native` ,這樣同時會創建一個`node_modules/`的目錄。3.  創建js文件,編寫React Native組件的js代碼。4.
  • 十大最受歡迎的 React Native 應用開發編輯器
    作者丨 Murtaza Basrai譯者 丨 安翔市面上用於開發工作的編輯器非常多,筆者會經常因為不同的程式語言該如何選擇好用的編輯器而感到糾結。而在隨後從事 React Native 開發工作過程中,對相應的編輯器做了一些探索和研究,本文總結了一些非常適合移動應用開發的編輯器和 IDE。1.
  • Flutter vs React Native:誰才是跨平臺應用開發的最佳利器?
    然而, Google 的 Flutter 是一個全面的舉動, 它允許你同時創建 Android 和 iOS 相應迅速的原生應用。在這個相互競爭的世界中, 移動應用開發公司的最終目標是選擇一個跨平臺框架, 使開發人員能夠編寫一個代碼庫並跨多個平臺進行部署, 共享儘可能多的代碼,、時間和成本。這樣的話, 我們就可以幫助我們的客戶選擇一個合適的框架, 最好地支持他們,實現他們的目標。
  • 用JavaScript開發移動原生應用,Facebook正式開源React Native!
    在經過前一天Messenger應用平臺、Parse物聯網開發者工具等驚喜的轟炸,Facebook於今天凌晨在F8開發者大會上正式開源了React Native。不過目前,只有iOS版,Android版還需要再等一段時間,這是最新的用JavaScript語言開發原生App的嘗試,其示例代碼相當簡潔,內置控制項也不少。
  • React Native 已死?
    20 日晚,Airbnb 在 Medium 上發博文宣布,「由於許多技術上和組織上的問題,我們決定放棄 React Native,將所有精力投入到原生應用上。」)Part 2:React Native at Airbnb: The Technology(https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)Part
  • ReactNative學習資源大匯集
    native中文網,人工翻譯,官網完全同步) http://react-native.cn/docs/getting-started.htmlreact-native第一課 http://html-js.com/article/2783深入淺出 React Native:使用 JavaScript 構建原生應用http://zhuanlan.zhihu.com/FrontendMagazine
  • Flutter 會不會被蘋果限制其發展?
    這個可能性是存在的,而且不止是 flutter、react-native 、weex 、uni-app 、taro 、Hippy等都存在這個風險,雖然有些框架對比起 flutter 其他框架存在時間稍長,但是這不可否認它們一直都存在這個風向。
  • Facebook 發布 React Native for Android
    React Native 讓開發者使用 JavaScript 和 React 編寫應用,利用相同的核心代碼就可以創建 Web,iOS 和 Android 平臺的原生應用。React Native 的宗旨是,學習一次,高效編寫跨平臺原生應用。
  • Shopify:用 React Native 打造移動應用開發的未來
    React Native 與 React 類似,它允許開發人員在 JavaScript 中創建聲明式用戶界面,為此它在內部創建一個 UI 元素的層次結構樹,用 React 術語來說就是創建一個虛擬 DOM。儘管 ReactJS 的輸出以瀏覽器為目標,但 React Native 使用平臺原生綁定將虛擬 DOM 轉換為移動原生視圖,這些平臺原生綁定使用 JavaScript 對接應用程式邏輯。
  • 分享 50 個完整的 React Native 項目
    順便說下,最近買了一個的域名:http://www.marno.cn 。不過暫時還沒想好放什麼內容,就先用 Github Pages 搭了一個簡單的網站,連結到了我整理的 React Native 優秀開源項目大全上。經常在微信群裡看到有一些正在學習 RN 的朋友在問,有沒有什麼比較適合入門的完整項目來參考學習下,今天就把我自己收藏的一些項目推薦給大家。
  • 推薦幾個 React Native UI 庫
    react-native-elementshttps://github.com/react-native-training/react-native-elementslottie-react-native相信不少開發者都聽說過 lottie,一個非常輕量級同時又支持多平臺的動畫庫,這個庫就是對應的 RN 版本了。
  • 沒 2 年 React Native 開發經驗,你都遇不到這些坑
    目前的折衷方案是文字的最後一行多加一個空格 or 零寬字符Android 有個屬性叫 includeFontPadding,設置為 false 後可以減少文字上下的 padding(這個 padding 是為角標字符預留的,例如 H₂O、2ⁿᵈ),這樣可以更好的實現上下垂直居中對齊實現文字的居中對齊時,最好用一個 View 嵌套一個 Text 標籤,然後給 View 設置一些 flex 屬性控制 Text
  • 推薦11 款 React Native 開源移動 UI 組件
    導航控制項 react-native-navbarreact-native-navbar 是用於 React Native 上簡單的定製化導航欄。React Native 輪播控制項 react-native-carouselreact-native-carousel 是一個簡單的 React Native 輪播控制項。
  • React Native 持續部署實踐— push 代碼構建出新版的 Growth
    最近我們正在使用 React Native 來重寫 Growth 應用,GitHub 地址:growth-ng 。
  • 如何用 React Native 開發一款電商 App?
    本文編譯自Hackernoon,原文標題為:Building an e-commerce search app with react native,推薦有一定編程基礎的讀者閱讀。今天我們來聊一聊是如何在RN平臺開發一款用於查找圖書資料庫的電子商務移動app。如果你之前沒有使用過RN,那麼現在就跟我一起開啟你的移動端Javascript開發之旅吧。
  • React Native vs. Flutter 評測
    之前分別用 iOS 原生和 Flutter 寫了一個空氣品質 App 並對它們對性能、容量等做了對比評測 《iOS 原生 vs.
  • 如何使用 React Native 構建實時 to do 應用程式
    我將在這個案例裡面使用最流行的移動框架之一 React Native 搭建一個待辦事項應用程式。我將使用 ReactiveSearch Native,這是一個提供 React Native UI 組件並幫助你快捷搭建數據驅動應用程式的開源庫。
  • Flutter 入門路線圖
    創建您的Flutter項目通過以下命令創建 flutter 項目flutter create <project-name>或者您可以使用IDE(Intellij,Android Studio等)項目概況當您創建 flutter 應用程式時,您會看到這些文件和文件夾,大多數代碼是用 dart 編寫在 lib 文件夾中,
  • 從零到一:用ReactNative開發的第一個跨平臺app
    ^5.0.6",(base64編碼)"react": "16.0.0-alpha.6","react-native": "0.44.2","react-native-camera": "^0.6.0",(掃碼)"react-native-deprecated-custom-components": "^0.1.0","react-native-easy-toast