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

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

作者|GeekyAnts

譯者|無明

來源 | 前端之巔

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

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

試水 Flutter

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

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

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

語言棧

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

JavaScript

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

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

Dart

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

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

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

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

  • 在 checked 模式下,它將啟用動態類型斷言。如果代碼中包含了靜態類型,那麼可以打開類型斷言。在開發和測試時建議使用 Checked 模式,因為它有助於在類型不匹配時捕獲代碼中的錯誤。
  • 生產模式是 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 的一些最好的特性,幫助開發人員構建出漂亮的跨平臺移動應用程序。

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

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

樣式

React Native

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

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

Flutter

樣式的差異在 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 (

Lorem Ipsum

);

}

}

const styles = StyleSheet.create({

greybox: {

backgroundColor: #e0e0e0,

width: 320px;

height: 240px;

font: 900 24px Georgia;

}

})

// skip this line if using Create React Native App

AppRegistry.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

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

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

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

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

Flutter

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

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

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

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

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

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

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

用戶界面

React Native

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

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

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

Flutter

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

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

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

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

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

Inkwell

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

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

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

GestureDetector

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

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

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

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

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

DefaultTabController

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

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

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

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

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

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

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

插 件

React Native

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

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

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

Flutter

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

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

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

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

社區

React Native

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

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

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

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

Flutter

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

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

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

問題

React Native

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

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

Flutter

如果你有使用 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


分享到:


相關文章: