接觸 React 其實也一段時間了,總是嚷嚷想做個自己的 Project 但始終沒有動手開始做。最近趁著寒假終於用 React 做了個網頁小遊戲,之後也改寫成 React Native 做出 Android and iOS 的原生 app,順便把 android 版上架到 Google play 上~(iOS app store 費用太高付不起…)
算是完成幾個長久以來的小小目標(?)
用 React Native 做出 Android/iOS 原生 app說真的寫好 React 版本以後要改寫成 React Native 還挺容易的,基本上要改的只有介面的部分,對應到程式碼大概就是每個 Component 中的 render(),當然還有 CSS 要改成 react-native 的 style,Animation 也不能用 CSS 來做了,這也是比較麻煩的地方。
檔案結構
React 版跟 React Native 版的檔案結構其實幾乎都是差不多的,可以看下圖的對應:
左圖是 React 的檔案結構;右圖是 React Native 的檔案結構。最大的差異是 style/ 資料夾不見了,這是因為 React Native 的 style 我都寫在 components 檔案裡面了。React 版本的 index.js 是進入點。其他檔案基本上都維持一樣的結構、React 版本定義的 components 在 react-native 版中都依舊存在。
左為 React 版;右為 React Native 版,元件完全一致。改寫 render()
邏輯可以重用,要改的只有渲染的部分。
我在改寫的時候,反正第一步就是把 <div> 通通改成 <View> ,把包住文字的 <span>、<div> 改成 <Text> ,這樣大概就完成一半了吧(?)
剩下的一半就是找找最適合的 native component ,這些可以上官方文件尋找。
改寫 Style
看似像 CSS,但又沒這麼好用,比較像是閹割版的 CSS。
React Native 的 style 是個 javascript 的物件,大概有七成可以跟 CSS 直接對應,寫法就是原本 CSS 改成 camlCase 寫,如果要寫得像 css 的 class 的話還要使用 StyleSheet.create() :
1 | // css |
套用樣式的寫法則是直接用 style={Object} ,若要套用複合樣式,則在 style 中放一個 object array(順序有差):
1 | <View> |
Animation
原本 React 版的動畫全都是用 css 做出來的,但這些在 React Native 中就沒辦法用了,官方有提供 Animation 相關的 API,但說實在的真的有點難搞。
後來我是用某大神寫的 library react-native-animatable,比起官方提供的更好用。
Divide and Conquer
改寫要一部份一部份改比較容易,一次要全改只會要你命!
從 React 改成 React Native 雖然好像不用費很大的功夫,但是如果想要一次到位全部改好其實還是很困難的。
我這個 Project 已經是很小規模的了(約 500 多行),但第一次想一次到位時我花了一兩個小時還是連 build 都沒辦法成功。所以果然還是一部份一部份改起來比較輕鬆。
以我的例子而言,是先改 <StatusPanel/> ,因為只要會倒數就好嘛,單純了自然就比較好寫;再來改 <ArrowKey/> 最後才是改 <QuestionList/> 跟 <Question/> ,這樣分批改前前後後大概只花兩個小時就全部搞定了。
一些坑以及一些筆記
進入點註冊程式就好
React Native 官方 example 的主程式都是寫在 index.android.js (或 .ios.js ) 裡面,個人感覺是可以把主邏輯拆出來,進入點只負責註冊程式就好:
1 | import { AppRegistry } from 'react-native'; |
iOS 樣式有差
即使用一模一樣的 code,iOS 跑起來樣式跟 android 的還是有差別,這我也不知道為甚麼,反正最後記得針對 iOS 的樣式再修改修改。
不能 react-native run-ios
假設遇到這問題,首先先檢查 port 8081 有沒有被佔用了:
1 | $ lsof -n -i4TCP:8081 |
如果問題沒排除,試試
1 | sudo react-native run-ios |