從零開始的Android新項(xiàng)目10 - React Native & Redux

原文鏈接:http://blog.zhaiyifan.cn/2016/08/04/android-new-project-from-0-p10/

本篇來講講 React Native 和 Redux扶认,和其他一上來就啪啪啪丟上來一堆翻譯的東西不同早像,本文會從簡單的例子入手,讓大家能快速地明白 React Native 是什么蚕冬,Redux 和常見的 MVC际插、MVP 等有什么區(qū)別恰力,怎么去組織一個 Redux 架構(gòu)的 React Native 項(xiàng)目捻艳。

為避免大家還沒入門就放棄,預(yù)計(jì)下一篇才會從我們項(xiàng)目中的實(shí)踐出發(fā)舆床,講講更復(fù)雜的應(yīng)用場景。

什么是React Native

React Native

React Native 使你能夠基于 JavaScript 和 React 在原生平臺上構(gòu)建應(yīng)用,提倡的是 “l(fā)earn once, write anywhere”挨队,復(fù)用代碼谷暮,提高開發(fā)效率。

項(xiàng)目由 Facebook 開源驅(qū)動盛垦,在過去的近一年中更新很活躍湿弦。文檔建議直接看官網(wǎng)的 React Native,中文站有點(diǎn)坑腾夯。

支持系統(tǒng):Android 4.1 (API 16) 以及 >= iOS 7.0颊埃。

關(guān)于 React,可以參見之前為掘金翻譯計(jì)劃翻譯的 React.js 新手村教程蝶俱,簡單來說 React 將應(yīng)用分為一個個動態(tài)可復(fù)用的組件 —— View的渲染(JSX)班利、數(shù)據(jù)如何綁定到顯示、狀態(tài)的變更(State)榨呆、屬性(Props)都包含在組件內(nèi)部罗标。

React.js

整個應(yīng)用由一個個組件搭積木而成(組件式開發(fā)),而每個組件則由狀態(tài)驅(qū)動而變更积蜻。

React Native 正像它的名字闯割,將 React 帶到了原生世界,和 H5 不同的是竿拆,我們不再使用 CSS 和 HTML宙拉,而只有 js 為伴。我們也不再有那些 div, input 這些標(biāo)簽丙笋,而是由 View, TextInput 等等取代鼓黔,更符合原生開發(fā)者們的習(xí)慣。布局上不见,幸而有強(qiáng)大的 Flexbox 支持澳化,如果開發(fā)者們之前有使用或者看到過 Google 在 GitHub 發(fā)布的 Android 版 FlexboxLayout,相信對它會很熟悉稳吮。原生開發(fā)中的頁面棧缎谷,也由 Navigator 進(jìn)行了實(shí)現(xiàn)(在 Android 上還有 BackAndroid 的返回鍵支持)。

與 WebView 不同灶似,React Native 運(yùn)行的界面列林,最終會被解釋映射為原生的 View,可以直接使用布局邊界或者 Hierarchy Viewer 看出層級(js 文件會打包為一個bundle酪惭,位于assets下面希痴,RN引擎會加載并進(jìn)行解釋映射)。

好處

  • 體驗(yàn) web 開發(fā)的便捷春感,不再需要編譯砌创,重新加載一下 js 就行了
  • 可以直接使用 Chrome 或者 Nuclide 調(diào)試
  • Android / iOS 兩端可以共享很大一部分代碼(RN 還在進(jìn)行 Windows, MacOS, Node-webkit 等平臺的支持)
  • 熱更新虏缸,JS bundle 下發(fā)一下新的就行了(當(dāng)然也有一定局限性,如果是 hybrid嫩实,則 native 的 RN module 部分不能更新)

壞處

  • 前端開發(fā)不會原生做不了 React Native(除非你能真只用自帶的那些東西)刽辙,而且理解那些 RN 提供的組件也會很頭暈(需要同時了解 Android 和 iOS)。
  • 原生開發(fā)需要一定成本的學(xué)習(xí)實(shí)踐才能掌握 React Native甲献。畢竟 ES6 不像過去的 JS 那么傻瓜式了宰缤。
  • React Native 目前仍然處于快速迭代開發(fā)的階段,你永遠(yuǎn)也不知道下個版本自己升級需要修改多少原來的代碼晃洒。
  • React Native 的資料較少慨灭,尤其是國內(nèi)的,更尤其是 hybrid 開發(fā)的(GitHub 上的開源項(xiàng)目大多是純 RN 的)球及。

什么是Redux

Redux.js
Redux.js

Redux 本身和 React 并沒有特別緊密的聯(lián)系氧骤,而是 Facebook 提出的 Flux 架構(gòu)的一種優(yōu)秀實(shí)現(xiàn),可以搭配其他任何框架一起使用桶略。在 React 上使用语淘,需要搭配 react-redux(如此一來 Redux 可以不局限于 React诲宇,而讓社區(qū)發(fā)展出更多的 redux-* 中間件)际歼。

Redux 在 React 的基礎(chǔ)上(state 和 props),增加了 store姑蓝、action鹅心、reducer 的概念,規(guī)范了全局一個 state纺荧,從而只需要根據(jù)這個 state 就能回朔出整個應(yīng)用的狀態(tài)旭愧。組件通過 dispatch 將 action 傳到 store,reducer 根據(jù)原來的 state 以及 action宙暇,返回新的 state输枯,組件根據(jù)新的 state 渲染界面。

Redux 是一個可預(yù)測的狀態(tài)容器占贫,即只需要有狀態(tài)樹桃熄,就能還原出“事發(fā)現(xiàn)場”。

從例子看項(xiàng)目

為了避免說一大堆概念型奥,大家一頭霧水瞳收,似懂非懂,這里拿一個例子來講講 React Native 和 Redux 結(jié)合后的效果厢汹,盡量避免代碼的出現(xiàn)螟深,而以圖和文字代替。

Counter烫葬!沒錯界弧,就是 Counter凡蜻,不是 TODO,TODO已經(jīng)被黑的不成樣了夹纫。

項(xiàng)目源碼位于:example-react-native-redux咽瓷。包含了 CounterCounters 兩個子項(xiàng)目。前者是單個的計(jì)數(shù)器舰讹,后者則在前者的基礎(chǔ)上增加了可以加減計(jì)數(shù)器個數(shù)的功能茅姜,相對更復(fù)雜一些,不過引入了一些不錯的實(shí)踐可以參考月匣。

運(yùn)行效果

先看看最后的效果钻洒,方便對應(yīng)后面的解說。
第一個 Counter 項(xiàng)目很簡單锄开,就是一個文本框加上兩個按鈕素标,一個加1,一個減1萍悴。
第二個 Counters 項(xiàng)目在前者的基礎(chǔ)上(使用了 Counter 組件)头遭,可以增加任意個計(jì)數(shù)器,還添加了帶延遲的加1功能癣诱,來模擬耗時操作计维。

Counter

先看看Counter,我們從物理架構(gòu)和動作流兩個角度來進(jìn)行觀察撕予。

目錄下鲫惶,有以下文件:

Counter List Files

index.android.js 和 index.ios.js 分別是 android 和 iOS 的 rn 入口,通常內(nèi)容是相同的实抡。
android 為 Android 的工程目錄欠母,下面有我們熟悉的 build.gralde。
ios 為 iOS 的工程目錄吆寨,包含了 xcode 的項(xiàng)目赏淌。
app 就是 rn 的目錄,包含了 Android 和 iOS 項(xiàng)目共享的 js 源碼啄清。
node_modules 是 node 通過解析 package.json 下載的依賴六水。

物理結(jié)構(gòu)

Counter物理結(jié)構(gòu)

CounterApp.js 則是整個應(yīng)用的實(shí)際入口。

動作流

且不談那些具體的 bind 和 createStore 操作盒延,我們來看看當(dāng)發(fā)生交互的時候缩擂,整個動作的分發(fā),拿點(diǎn)擊加號為例:

Counter活動圖

onPress 事件觸發(fā)了后續(xù)的一系列活動添寺,而 Counter Component 的 action function 則由外部通過 props 傳入(在這里胯盯,是 CounterApp 的 render 函數(shù),如下)计露。

counterApp.js

再看看 store 的創(chuàng)建博脑,在 App.js 入口:

app.js

而 Component 也不是直接調(diào)用 action 的 function憎乙,而是通過 bindActionCreators 注入到組件props中(這里是通過 react-redux 進(jìn)行的,不是 redux 自身的東西叉趣,可以理解為 react 和 redux 之間的膠水):

action bind

通常我們會在智能組件的末尾使用:

export default connect(mapStateToProps, mapDispatchToProps)(CardDetail);

這樣來把 state 以及 action 注入泞边。

Counters

接著我們來看看更為復(fù)雜的 Counters 項(xiàng)目,頂層目錄結(jié)構(gòu)類似疗杉,不再贅述阵谚。

demo

看完上面的 demo 動圖后,相信大家對下面的解說會更容易理解烟具。

物理結(jié)構(gòu)

Counters物理結(jié)構(gòu)

我們來詳細(xì)講一下 modules 下的 app 目錄中的文件組織梢什。

actions.js 和剛才一樣,定義了一個個的 action朝聋,略有不同的是由于這次有異步的操作嗡午,所以涉及到了 dispatch 函數(shù),關(guān)于 dispatch 可以查看官方文檔冀痕。

constants.js 定義了所有 action 的 type荔睹,以及 App 的名字。

reducers.js 一樣根據(jù) action(payload 和 type)以及原來的 state 返回新的 state言蛇,另外僻他,這里還進(jìn)行了 initial state 即初始狀態(tài)的定義(我們也可以把它放到單獨(dú)的文件中)。

App.js 定義了頁面的布局(渲染和 action)猜极,導(dǎo)出了 connect 生成的 container中姜。我們簡單看一下 render 部分是怎么做的消玄。

Counters render

怎么樣跟伏,JSX 是不是挺容易理解的?

動作流

Counter 本身的動作流上面我們已經(jīng)舉例過了翩瓜,本工程中增減計(jì)數(shù)類似受扳,唯一的區(qū)別是 action 不只有 type,還帶了 payload(id)來標(biāo)示不同的計(jì)數(shù)器兔跌。

所以這里我們拿增加計(jì)數(shù)器的點(diǎn)擊事件來做例子勘高。

Add Counter

看上去是不是跟上面的差不多?剩下的那個 incrementWithDelay 其實(shí)也差不多坟桅,只不過返回的是一個function华望,在 setTimeOut 回調(diào)中才進(jìn)行 dispatch(thunk middleware 會幫我們進(jìn)行處理)。

總結(jié)

上面我們通過物理結(jié)構(gòu)和活動圖大致了解了 React Native 上的 Redux 架構(gòu) app 是如何工作的仅乓。具體的細(xì)節(jié)赖舟,建議大家還是去查看 GitHub 上的源代碼,通過上面的講解后夸楣,應(yīng)該不難理解宾抓。

技術(shù)棧

我們目前實(shí)踐的React Nataive技術(shù)棧:

  • immutable.js
  • react
  • redux
  • react-redux
  • redux-thunk
  • redux-logger
  • redux-mock-store
  • react-native-router-flux
  • react-native-simple-store
  • regenerator
  • undefined
  • jest

更多閱讀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缕棵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涉兽,更是在濱河造成了極大的恐慌挥吵,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件花椭,死亡現(xiàn)場離奇詭異忽匈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)矿辽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門丹允,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人袋倔,你說我怎么就攤上這事雕蔽。” “怎么了宾娜?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵批狐,是天一觀的道長。 經(jīng)常有香客問我前塔,道長嚣艇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任华弓,我火速辦了婚禮食零,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寂屏。我一直安慰自己贰谣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布迁霎。 她就那樣靜靜地躺著吱抚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪考廉。 梳的紋絲不亂的頭發(fā)上秘豹,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機(jī)與錄音芝此,去河邊找鬼憋肖。 笑死因痛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岸更。 我是一名探鬼主播鸵膏,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怎炊!你這毒婦竟也來了谭企?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤评肆,失蹤者是張志新(化名)和其女友劉穎债查,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓜挽,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盹廷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了久橙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俄占。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖淆衷,靈堂內(nèi)的尸體忽然破棺而出缸榄,到底是詐尸還是另有隱情,我是刑警寧澤祝拯,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布甚带,位于F島的核電站,受9級特大地震影響佳头,放射性物質(zhì)發(fā)生泄漏鹰贵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一畜晰、第九天 我趴在偏房一處隱蔽的房頂上張望砾莱。 院中可真熱鬧瑞筐,春花似錦凄鼻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膘格,卻和暖如春峭范,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瘪贱。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工纱控, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辆毡,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓甜害,卻偏偏與公主長得像舶掖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子尔店,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容