Yuanlin Lin

Blog

原來 App 開發這麼簡單!React Native 基本介紹

Yuanlin Lin 林沅霖

2022-05-17

如果你是 Web 前端工程師,或是剛學會 HTML, CSS, JS 然後正在煩惱要接著學哪個前端框架的同學,你一定聽過 React, Vue, Angular 這三大框架吧!這三大框架之中我最喜歡的就是 React 了,暫時撇開他們各自的學習難度、語法特性等比較常見的比較,今天這篇文章想和大家聊聊我主要喜歡 React 的另一個原因 - React Native

封面圖 Unsplash @ Timothy Hales Bennett

React 的語法

為了避免讀者還不知道 React 是什麼,這邊做一個簡短的介紹。

相較於以前傳統在網站上直接對 DOM 進行操作(或是透過 jquery 這類的工具),現代前端框架的一個主要任務就是讓你在開發的時候能夠忘記 DOM 的存在,把注意力集中在程式的邏輯上,比如說如果不用框架想要做一個網頁時鐘:

<div id="clock"></div> <script> var clock = document.querySelector('#clock'); var renderTime = function () { var time = new Date(); clock.textContent = time.toLocaleString(); }; setInterval(renderTime, 1000); </script>

我們需要先用 document.querySelector 找到我們要更改的元素,然後再把這個元素的 textContent 改掉。但如果我們用 React 來做的話:

function MyClock() { // time 是 MyClock 組件的一個狀態 (state) const [time, setTime] = useState(new Date()); // 在 MyClock 組件被建立以後,啟動一個 Interval 讓他每 100ms 更新一次狀態 useEffect(() => { setInterval(() => { setTime(new Date()); }, 100); }, []); return <div>{time.toLocaleString()}</div>; }

是不是覺得整體邏輯清楚許多呢!我不需要思考如何從 DOM 取得我想要操作的元素(React 會幫我管理我的組件和 DOM 之間的關係),也不需要思考什麼時候需要更新 DOM 的內容(React 組件有自己的 lifecycle 來判斷渲染的時機),讓開發的時候可以更專注在邏輯層面。

用 React 做出了一個簡單的時鐘網站

React Native 的語法

知道 React 如何使用以後,你已經可以在瀏覽器上用 React 實現出各式各樣的網頁程式了。然而,實際上這套邏輯可以被使用在任何程式開發,因為我們在使用 React 框架的時候並沒有出現任何對於程式運行環境有所依賴的語法(例如 document.querySelector 就要求一定要在瀏覽器上執行,因為瀏覽器才有 document 這個東西)。

而 React Native 就是利用了這個特性,既然我們在使用框架的同時,完全只是在做程式邏輯層面的定義,那意味著我們可以用一模一樣的寫法,定義一模一樣的邏輯,但是在不同平台執行!

note:眼尖的同學可能發現了,<div> 這個東西也是瀏覽器內的東西啊!沒錯,所以在 React Native 中,我們不用這些瀏覽器內的標籤,而是用 React Native 提供的那些組件來替代,例如用 <View>

用前面的時鐘例子,你已經會用 React 寫一個網頁時鐘了,我們只要把這個 Component 做一點點小調整,變成:

function MyClock() { // time 是 MyClock 組件的一個狀態 (state) const [time, setTime] = useState(new Date()); // 在 MyClock 組件被建立以後,啟動一個 Interval 讓他每 100ms 更新一次狀態 useEffect(() => { setInterval(() => { setTime(new Date()); }, 100); }, []); return <View> <Text>{time.toLocaleString()}</Text> </View>; }

恭喜你,你現在不僅會寫一個網頁時鐘,而且還會寫一個 App 時鐘了 🎉

等等,這兩個程式碼根本沒有差別啊!只不過是把 <div> 換成了 <View> 然後文字外面套了一層 <Text> 而已呀!

沒錯,這就是 React Native 的優勢,我們可以完全用和開發網站相同的語法和邏輯,甚至是整體的組件架構,直接套用到 App 開發中,這樣不僅大大降低了 App 開發的學習成本,甚至對於同時需要網站和 App 的專案來說,還可以重複使用大量的程式碼,降低了開發和維護成本!

React Native 不就是 Webview 嗎?

這是很多人對 React Native 的一個誤解。先和沒瞭解過 Webview 的同學介紹一下:所謂的 Webview 就是在 App 裡面寫一個類似於嵌入在 App 內的「瀏覽器」,所以當你安裝了這個 App 實際上只是在手機上安裝了另一個瀏覽器,然後這個嵌入在 App 的瀏覽器會載入你寫的 HTML, CSS, JS 檔案,然後顯示在畫面上。

圖片來源:https://codeburst.io/why-and-when-cordova-is-better-then-react-native-2519852ae06a

這個作法有一個好處,那就是你隨時更新線上的網站(那些 HTML, CSS, JS 檔案),你的 App 一打開就可以看到新的畫面,因為你 App 裡面實際上也是一個網站。但壞處也很顯而易見,那就是你最後寫出來的東西終究只是一個套著 App 殼的網站,所以操作起來無法像 App 一樣流暢,也無法使用 App 才能用的各種原生能力。


那 React Native 是不是 Webview 呢?實際上並不是的,因為 React Native 寫出來是一個真正的原生 App,而不是套著 App 外殼的網站。只是這個原生的 App 裡面有一個 JS 引擎,我們用這個 JS 引擎來執行 React 的程式,然後 JS 透過一個稱作 Bridge 的東西來調度各種原生的 API:

圖片來源:https://collectivemind.dev/blog/react-native-re-architecture

好像開始有點複雜了,如果無法理解的同學也不用擔心,你只要知道 React Native 寫出來的 App,你所看到和摸到的部分都和原生的 App 一樣,唯一不同的是 React Native 通過 JavaScript 程式來調度這些內容,所以我們可以用基於 JavaScript 語言的 React 開發 App。

React Native 的優缺點

除了上面說的,我們可以用和寫網站相同的語法開發出媲美原生體驗的 App 之外,React Native 還有一些優點:

  1. 同時開發 iOS 和 Android 雙平台的 App
  2. JavaScript 的部分能夠 OTA 更新,使用者不需要重新去 App Store 下載更新
  3. 可以使用 JavaScript 生態豐富的套件
  4. 如果真的遇到 JavaScript 實現不了的功能,直接用 Swift 和 Kotlin 開發 native module 再加進來 React Native App 也完全 OK

那他有什麼缺點呢?這邊不僅針對原生 App 開發,也做出了一些相較於其他 Hybrid App 開發可能的缺點:

  1. 對於相同的功能,用 JavaScript 和用原生語言相比,效能肯定還是差了一點
  2. 相比於完全捨棄原生的 UI 渲染(例如 Flutter),React Native 需要花額外的時間調整相同組件在 iOS 和 Android 平台呈現的效果不一樣的問題

哪些 App 是用 React Native?

如果聽完上面的介紹,你還是對是否要學習 React 或是是否要用 React Native 來開發你的下一個 App,不妨去 App Store 下載這些用 React Native 開發的 App 用用看:

Facebook, Instagram 居然是 React Native 開發的,你相信嗎?

Discord, Pinterest, Tesla 也是 React Native 開發的

原來我每天用 Uber Eats 叫外送,也是 React Native 寫的!

什麼是 Expo

如果你閱讀到這邊開始對 React Native 開始有點興趣了,你會發現網路上大部分的資料都提到了 Expo 這個東西。

Expo 究竟是何方神聖

就像前面所說的,React Native 因為不是單純的 Webview 技術,因此開發 React Native App 其實本質上就是開發原生的 App (而且是兩個原生的 App,Android 和 iOS 各一個),這導致他的開發環境設定會相對麻煩一點,甚至沒有 mac 的話就沒辦法進行 iOS 的測試了 😭

這時候 Expo 就是一個救世主了,他的存在就是為了抹平我們和 App 開發的最後一哩路。安裝了 Expo 以後,我們真的可以用一個指令直接開始 App 開發:

expo init

輸入以後他會問你幾個關於你新的專案的問題,例如名字是什麼?要用什麼模板?用 JavaScript 還是 TypeScript?回答完以後你的專案就初始化好了。

當你開發好你的 App 了,我們要把他編譯成 .aab.ipa 檔案,才能上架到 Play Store 和 App Store,這一步可能又會卡住很多人,因為編譯這些程式除了 JavaScript 的部分,還有很多原生的 Java, Kotlin, Swift, Objective-C 等程式語言要處理,這時候 Expo 又要幫大忙啦,他的 Expo Application Services (EAS) 可以免費提供伺服器主機幫我們編譯,讓我們不需要花時間設定麻煩的開發環境。

note:Expo 雖然方便,但同時也會對我們能夠使用的原生體驗帶來一些限制。我們必須在「擴展性」和「方便性」之間進行權衡,如果我們要開發的是一個功能簡單的小 App,那我們可以用 Expo 的 managed workflow 來享受方便的開發體驗,但如果我們是一個大型、複雜且用到很多原生能力的 App,就要考慮用 Expo 的 bare workflow 來使用這些更底層的原生功能。

結語

這篇文章用一個比較科普、概念性的角度和大家介紹了一下 React Native 這個東西,他對於同時需要網站和 App 的團隊和新創公司而言,無非是一個強力的殺手鐧,對網頁前端開發者而言,也是一個提升自我價值的工具,畢竟不需要額外學習新的語言,就能用自己最熟悉的 React 語法邏輯完成原生的 App 開發。

希望看完這篇文章以後能夠讓還在觀望 React Native 的你邁出步伐,或是讓還在猶豫要學 React, Vue 還是 Angular 的你有更多角度可以參考。如果你和我一樣對軟體開發、產品設計有興趣,歡迎來我們的 Chief Noob Discord Server 一起交流 👍

author-avatar

關於作者

Yuanlin Lin 林沅霖

台灣桃園人,目前就讀浙江大學,主修計算機科學與技術,同時兼職外包全端開發工程師,熱愛產品設計與軟體開發。

閱讀更多

回部落格首頁