基于 Redux 的 React Native 應(yīng)用架構(gòu)(1/2)

博客地址:http://davidleee.com
原文鏈接:http://davidleee.com/2017/04/20/Build-App-With-Redux/

自從 Facebook 把 React Native 給開源了之后,使用前端技術(shù)進行移動應(yīng)用開發(fā)的趨勢已經(jīng)越來越明顯赖草,現(xiàn)在連微軟爸爸都用上了 React Native(ReactXP)往果,我們還有什么理由不來一點前端技術(shù)嘗嘗呢?

這篇文章是學(xué)習(xí)了公司現(xiàn)有項目框架围来、外加查閱一些官方文檔之后的總結(jié)底扳,受限于我僅有的一丟丟前端知識请垛,如果有錯誤或沒講清楚的地方餐抢,歡迎在評論里給我留言 :)

因為要把現(xiàn)有項目講清楚內(nèi)容較多,所以分為兩個部分來總結(jié)荐绝。這篇是第一個部分一汽,主要涉及 Redux 思想的簡單應(yīng)用。


試想一下...

我們從一個實際可能會遇到的需求出發(fā)低滩,考慮一下 Native 的實現(xiàn)和 React Native 的實現(xiàn)有什么不同召夹。

來需求了

用戶在登錄之后,在首頁要顯示用戶的頭像和名字恕沫,然后還應(yīng)該可以在某個地方看到自己的全部信息监憎。

( oωo ) 那還不簡單!用戶登錄之后拉一下服務(wù)器上的用戶信息婶溯,找個合適的界面把信息一股腦顯示出來就好了鲸阔,done!

簡單地改一下

用戶想要在我們的 App 上編輯自己的信息迄委,我們簡單點來隶债,直接在信息顯示的界面提供個編輯的入口就好了。

∑( ̄□ ̄;) ......嗯跑筝,這個要求也合情合理死讹。

編輯之后發(fā)個消息通知其他地方,比如首頁的頭像和名字就可能要更新...某個列表似乎會根據(jù)用戶性別來決定顯示的內(nèi)容曲梗,不過什么人會用著用著修改性別赞警?!

來虏两,這個更加簡單

果然修改一下用戶信息很簡單嘛愧旦,那再改回去也是一個道理吧,提供一個撤銷修改的按鈕吧定罢。

Σ(°Д°; 這笤虫!


為什么用 Redux

如何優(yōu)雅地實現(xiàn)上面的需求呢?如果我們的界面是與數(shù)據(jù)綁定的祖凫,并且數(shù)據(jù)的每一個狀態(tài)我們都可以追蹤到琼蚯,那我們就不需要理會界面的更新,而可以專注于數(shù)據(jù)的修改了惠况。

React Native 已經(jīng)為我們提供了視圖與數(shù)據(jù)綁定的機制遭庶,那么狀態(tài)要怎么追蹤呢?

什么是 Redux

Redux 是一個為 JavaScript 應(yīng)用設(shè)計的可預(yù)測的狀態(tài)容器稠屠。

簡單來說峦睡,Redux 使用了一種叫做 Action 的東西翎苫,每一次對狀態(tài)的變更(也就是對數(shù)據(jù)的變更)都需要通過 Action 來進行,然后通過另一個叫做 Reducer 的東西將 Action 和數(shù)據(jù)聯(lián)系起來榨了。下面這張流程圖應(yīng)該可以幫助你理解:

Flux

這張圖來自 Flux煎谍,Redux 可以被理解為是 Flux 的具體實踐。

顧名思義龙屉,Action 是一個操作呐粘,也可以理解為將要發(fā)生的事件,例如“修改用戶名”叔扼、“撤銷修改”;而 Reducer 則位于上圖 Dispatcher 和 Store 之間漫雷,負責將 Action 反應(yīng)到對 Store 的修改上瓜富。

初衷

在上面的需求中,如果可以記錄下用戶的每一個操作和操作后的狀態(tài)降盹,那么當用戶想要撤銷某項操作時与柑,只需要將上一個操作給無效掉就可以了。更暴力一些蓄坏,我們把應(yīng)用啟動至今的所有用戶操作都重播一遍价捧,唯獨不執(zhí)行最后一次操作,就實現(xiàn)了“撤銷”的功能了吧涡戳?

Redux 提供的機制正好滿足了這個需求结蟋。

不止如此

React Native 實現(xiàn)的應(yīng)用可以類比為使用 JavaScript 實現(xiàn)的單頁應(yīng)用,隨著開發(fā)日趨復(fù)雜渔彰,我們的應(yīng)用需要管理的狀態(tài)(state)會變得越來越多嵌屎,管理的難度也將成倍增加。

Redux 提供的機制恍涂,通過限制數(shù)據(jù)更新發(fā)生的時間和方式宝惰,使得 state 的變化變得可以預(yù)測,后續(xù)的開發(fā)也可以放手施展了再沧。


那該怎么做呢尼夺?

接下來我們分別看看 Redux 中主要的三部分是怎么實現(xiàn)的。

Action

為了描述一個動作炒瘸,我們需要給這個動作一個名字和這個動作要操作的數(shù)據(jù)淤堵。舉個栗子,對于用戶想要改變用戶名的情況顷扩,我們可以這樣聲明這個動作:

// actions.js

export const CHANGE_USERNAME = 'CHANGE_USERNAME' // 1

// 2
export function changeUsername(username) {
  return { type: CHANGE_USERNAME, username}
}
  1. 首先我們將這個動作稱為 CHANGE_USERNAME粘勒,理論上每一個 Action 都應(yīng)該有一個獨一無二的名字
  2. 通過一個創(chuàng)建函數(shù),創(chuàng)建這個 Action 對象返回給調(diào)用方

例子里的動作名和創(chuàng)建函數(shù)都是 export 的屎即,因為一般會把同一個模塊的動作聲明放到一起庙睡,方便外部的調(diào)用事富。

Reducer

需要注意的是,Reducer 必須是一個純函數(shù)乘陪。它不能修改傳入的參數(shù)并且不能有任何副作用统台,它必須要保證只要兩次傳入的參數(shù)相同,得出的結(jié)果也要相同啡邑。

先看代碼:

// reducers.js

import { CHANGE_USERNAME } from './actions'

// 1
const initialState = {
  username: ""
}

function demoApp(state = initialState, action) { // 2
  switch (action.type) { // 3
    case CHANGE_USERNAME:
      return { // 4
        ...state,
        username: action.username
      }
      default:
        return state // 5
  }
}

export default demoApp
  1. 在 Redux 應(yīng)用中贱勃,所有的 state 都被保存在一個單一的對象中
  2. 這里用到了 ES6 中的參數(shù)默認值語法,省去了初始化 state 的過程
  3. 當需要處理多個 Action 的時候谤逼,可以用 switch贵扰、if/else 等方式區(qū)分不同的處理方式
  4. 再次強調(diào),Reducer 必須是一個純函數(shù)流部,所以使用對象展開運算符把傳入的 state 展開戚绕,避免修改到里面的參數(shù)
  5. 還是因為純函數(shù)的原因,在不處理任何 Action 的時候枝冀,需要將傳入的 state 原封不動地再傳回去

通過上面的 Reducer舞丛,當有 CHANGE_USERNAME 這個動作發(fā)生時,應(yīng)用會通過 demoApp 方法來更新 state 中的 username 參數(shù)果漾,如果有視圖綁定在這個參數(shù)上球切,則界面也會發(fā)生相應(yīng)的改變。

Store

有了 Action 和 Reducer绒障,我們還需要將這二者聯(lián)系起來的途徑吨凑,稱為 Store。

Store 還具有維持應(yīng)用 state 的職責户辱,所以它在應(yīng)用中也是單一存在的怀骤。當需要拆分數(shù)據(jù)處理邏輯的時候,應(yīng)該做的是拆分 Reducer 而不是創(chuàng)建多個 Store焕妙。

繼續(xù)來看代碼:

// store.js

import { createStore } from 'redux'
import demoApp from './reducers'
let store = createStore(demoApp)

沒啦蒋伦!我們需要用到的是 store 里面的方法,所以主要還是來看看怎么使用它們吧焚鹊。

調(diào)用

直接來看代碼痕届,我們假設(shè)已經(jīng)存在一個用戶信息界面,用戶將在這里修改自己的名字:

// UserInfo.js

import { changeUsername } from './actions'
import { store } from './store'

store.dispatch(changeUsername("Lee")) 

在這里末患,我們通過 changeUsername 方法構(gòu)造了一個 Action研叫,并告訴它我們要把名字改成什么;通過 store 中的 dispatch 方法璧针,這個 Action 就會被發(fā)送 Reducer 中進行處理嚷炉。

只是寫到這里,得益于純函數(shù)的實現(xiàn)探橱,我們就已經(jīng)可以給上述代碼中的所有方法寫單元測試了申屹,就是這么簡單绘证。


結(jié)語

上面的例子只涉及到了 Redux 最基本的使用方式,到目前為止還不能做出什么有用的東西來哗讥,不過用來讓我們感受 Redux 的主要思想應(yīng)該是足夠了嚷那。

在下一篇文章中,才會講到 Redux 應(yīng)用框架的搭建杆煞。其中會用到一些能有效減少代碼量的第三方框架(從上面的例子應(yīng)該不難想象魏宽,當程序變復(fù)雜之后,這幾個類會變得多么龐大)决乎。如果在學(xué)習(xí)了基礎(chǔ)知識之后還是看不懂一些現(xiàn)有項目的代碼的話队询,看完這些第三方框架的使用說不定就懂了呢!

更多更詳細的資料可以看參考資料中的網(wǎng)站构诚。關(guān)于 React Native 的部分建議上官網(wǎng)看原版蚌斩,我發(fā)現(xiàn)中文網(wǎng)的翻譯稍有缺失,更新也可能不那么及時唤反。


參考資料:
React Native
React Native 中文網(wǎng)
Redux 中文文檔
RNPlayground

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凳寺,一起剝皮案震驚了整個濱河市鸭津,隨后出現(xiàn)的幾起案子彤侍,更是在濱河造成了極大的恐慌,老刑警劉巖逆趋,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盏阶,死亡現(xiàn)場離奇詭異,居然都是意外死亡闻书,警方通過查閱死者的電腦和手機名斟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魄眉,“玉大人砰盐,你說我怎么就攤上這事】勇桑” “怎么了岩梳?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晃择。 經(jīng)常有香客問我冀值,道長,這世上最難降的妖魔是什么宫屠? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任列疗,我火速辦了婚禮,結(jié)果婚禮上浪蹂,老公的妹妹穿的比我還像新娘抵栈。我一直安慰自己告材,他們只是感情好,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布竭讳。 她就那樣靜靜地躺著创葡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绢慢。 梳的紋絲不亂的頭發(fā)上灿渴,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機與錄音胰舆,去河邊找鬼骚露。 笑死,一個胖子當著我的面吹牛缚窿,可吹牛的內(nèi)容都是我干的棘幸。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼倦零,長吁一口氣:“原來是場噩夢啊……” “哼误续!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起扫茅,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤蹋嵌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后葫隙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體栽烂,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年恋脚,在試婚紗的時候發(fā)現(xiàn)自己被綠了腺办。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡糟描,死狀恐怖怀喉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情船响,我是刑警寧澤躬拢,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站灿意,受9級特大地震影響估灿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缤剧,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一馅袁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荒辕,春花似錦汗销、人聲如沸犹褒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叠骑。三九已至,卻和暖如春削茁,著一層夾襖步出監(jiān)牢的瞬間宙枷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工茧跋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留慰丛,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓瘾杭,卻偏偏與公主長得像诅病,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子粥烁,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

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