關(guān)于Redux為核心的應(yīng)用開發(fā)簡(jiǎn)介


title: 關(guān)于Redux為核心的應(yīng)用開發(fā)簡(jiǎn)介
date: 2017-04-20 08:05:04
categories: React-native
tags: Redux


問題出發(fā)點(diǎn),當(dāng)我們?cè)赨I組件中執(zhí)行交互操作(點(diǎn)擊,滑動(dòng)诵竭,提交),我們要考慮到怎么來(lái)響應(yīng)操作.函數(shù)式編程里有個(gè)圖,有一個(gè)機(jī)器,從一邊放入肉,另一邊出火腿.這就是一個(gè)流程.application的操作其實(shí)就是解決點(diǎn)擊=>結(jié)果展示的流程.
但是實(shí)際流程中需要解決的問題很多.我們要考慮怎么來(lái)更好的管理application 的狀態(tài)問題. 具備javascript的基礎(chǔ)知識(shí),幾個(gè)模式設(shè)計(jì)的東西严就,函數(shù)式編程的知識(shí),React的知識(shí),Redux的思想.可以說(shuō)想在實(shí)際應(yīng)用中玩轉(zhuǎn)React/Redux/Redux-saga/immutable策泣。需要掌握的東西還是很多的.
我先寫一點(diǎn)具體的一些學(xué)習(xí)內(nèi)容和需要的思想.

輔助觀念轉(zhuǎn)變的一個(gè)生活實(shí)例

先看個(gè)電燈電路

電燈的原理圖
電燈的原理圖
  1. 控制開關(guān)執(zhí)行動(dòng)作(操作),
  2. 電燈根據(jù)開關(guān)的動(dòng)作來(lái)改變狀態(tài),
  3. 電燈的狀態(tài)不是由自己決定的,電路里有電了就會(huì)亮,沒電了就不亮,像木偶一樣受到控制.

飛機(jī)座艙

早期的座艙
早期的座艙

各個(gè)儀表都和自己的傳感器連接在一起跟束,加上冗余備份的儀表,很難設(shè)計(jì)和維護(hù)

先進(jìn)座艙
先進(jìn)座艙

80-90年代的window操作系統(tǒng)(不止windows奧),起源其實(shí)就是早期美國(guó)國(guó)防部的科研項(xiàng)目.
傳感器和顯示屏就沒有那么多線了.由數(shù)據(jù)總線來(lái)做集中統(tǒng)一處理.

理解React/Redux/Redux-saga架構(gòu)的基礎(chǔ)知識(shí)

函數(shù)式編程思想

函數(shù)式編程想的模擬香腸機(jī)器
函數(shù)式編程想的模擬香腸機(jī)器

函數(shù)式編程把流程拆為幾個(gè)有聯(lián)系的步驟,可以分解流程,易于維護(hù).合起來(lái)完成一個(gè)具體的任務(wù).
但是這只是函數(shù)式編程的一個(gè)組成部分
在javascript的函數(shù)式編程中用到很多概念

  1. 函數(shù)作為一類對(duì)象,可以作為數(shù)組的元素,可以作為函數(shù)的參數(shù)來(lái)傳遞.
  2. 基于流的編程(redux-saga就是基于流的編程).
    基于流的編程
    基于流的編程
  3. 閉包的概念


    閉包的概念圖
    閉包的概念圖
一個(gè)簡(jiǎn)單的閉包函數(shù)
一個(gè)簡(jiǎn)單的閉包函數(shù)

作為工具函數(shù)的閉包
作為工具函數(shù)的閉包
  1. high-order function 接受其他函數(shù)作為參數(shù)的函數(shù)
  2. 純函數(shù),對(duì)象的immutable,狀態(tài)改變.

一個(gè)實(shí)際的流程分析

在用戶提交表單的時(shí)候莺奸,我們想要做如下事情:

1. 校驗(yàn)一些輸入信息 (簡(jiǎn)單丑孩, 寫在組件里)
Validate方法,可以考慮導(dǎo)入redux-form組件,自帶驗(yàn)證方法
2. 驗(yàn)證以后可以讓提交按鈕改為可以提交狀態(tài)了
```
//login.UI.js登錄組件
this.props.dispatch(userLoginRequest(submit_info));
//已經(jīng)結(jié)束了,不要想太多,用戶和組件的交互就是表單輸入和提交按鈕
//所以這里也執(zhí)行這個(gè)過(guò)程就可以了.

 ```

3. 彈起提示信息(React組件化的優(yōu)勢(shì),公共組件)

```
   //login.Ui.js
  //Lodaing組件
 this.props.isFetching?<Loading>:null
 
```

4. 提交后端服務(wù) (我們用fetch,這個(gè)是不變的,redux只是對(duì)流程的控制,并不是要改變實(shí)際做事的方法)

5. 拿到后端返回狀態(tài) (promise resolve)
6. 隱藏提示信息 (鴻門宴啊,摔杯為號(hào),這不就是狀態(tài)嗎温学?)

 ```
   //login.UI.js
   this.props.isFetching?<Loading>:null
 
  ``` 

7. 更新redux store (reducer的操作)

  //login.reducer.js
  
  return state.merge(resolve.result);
  

8. 登錄界面的任務(wù)完成了.根據(jù)業(yè)務(wù)需要跳轉(zhuǎn)到對(duì)應(yīng)的頁(yè)面

  //reducer.js
  
  return state.merge(resolve.result);
  
  //login.js
  
  this.props.loginsuccess?(Action.Mycenter):(Action.refresh)
  

這里我們就把登錄的流程做了分解.好處是很多的,流程都是根據(jù)狀態(tài)來(lái)的變化的,
代碼書寫清晰,在每一步的dubug和測(cè)試過(guò)程都很容易,因?yàn)槲覀兛梢垣@取每一步的狀態(tài)

由于有redux-logger的中間件存在,我們還可以查看每一步的狀態(tài)變化.好像還有圖形化的界面來(lái)顯示state的變化.

總的原則是React組件只負(fù)責(zé)信息展示枫浙,簡(jiǎn)單的驗(yàn)證
復(fù)雜的邏輯現(xiàn)在全部在Redux中來(lái)實(shí)現(xiàn)

副作用(side effect)到底是個(gè)什么?

副作用其實(shí)就可以理解為由外部API提供的服務(wù).這個(gè)服務(wù)和我們的app的流程是沒有關(guān)系的,我們只需要給接口提供參數(shù),等待接口返回?cái)?shù)據(jù)就可以了.

React/Redux/Redux-saga

React的概念,原理

  1. React內(nèi)心是虛擬DOM,在react中的html代碼實(shí)際是React渲染的模板


    react組件中的html代碼叫jsx代碼,不是實(shí)際的html代碼,是js代碼
    react組件中的html代碼叫jsx代碼,不是實(shí)際的html代碼,是js代碼
  2. React渲染動(dòng)態(tài)內(nèi)容的方式通過(guò)外部父組件傳入的props和組件內(nèi)部的state來(lái)實(shí)現(xiàn)
    絕對(duì)不可以搞錯(cuò)的概念:組件之間要傳遞參數(shù)只能通過(guò)props來(lái)實(shí)現(xiàn),state只能在組件內(nèi)部使用,如果要把sate傳遞到其他組件,一定要經(jīng)過(guò)轉(zhuǎn)換
    在React中,props和state都有兩類不同的id來(lái)區(qū)分,不同的id類型是找不到對(duì)方的內(nèi)容的.Redux的mapStateToProps方法就是把State的類型id轉(zhuǎn)為props的類型id.
    由此可以得出什么結(jié)論呢紧帕?

其實(shí)Redux也是一個(gè)React的組件.

Redux的mapStateToProps函數(shù)的主要目的是什么是嗜?
Redux的mapStateToProps函數(shù)的主要目的是什么挺尾?

******切記,切記*******

3.Connect這個(gè)函數(shù)是非常重要的函數(shù)
組件要訂閱state的變化,能夠訂閱dispatch的方法都是通過(guò)connect函數(shù)來(lái)執(zhí)行的.

Redux的出現(xiàn)

Redux的流程圖
Redux的流程圖

Redux負(fù)責(zé)把React的邏輯處理獨(dú)立出來(lái)處理
Redux的要點(diǎn)有:

  1. 一個(gè)應(yīng)用只有一個(gè)state
  2. state是只讀的,這是immutable的概念.
  3. 修改state只能是用純函數(shù)來(lái)執(zhí)行,dispatch(Action(params))

一旦React的應(yīng)用中加入Redux的構(gòu)架以后魂挂,所有Appliction的核心就由組件轉(zhuǎn)變到Redux中了.如果和傳統(tǒng)的web的 browser/server來(lái)類比,Redux就變成了服務(wù)器的角色,state就承擔(dān)了數(shù)據(jù)庫(kù)的角色.

組件之前的state的改變現(xiàn)在要重新思考了.

Redux承擔(dān)了服務(wù)器和數(shù)據(jù)庫(kù)的角色
Redux承擔(dān)了服務(wù)器和數(shù)據(jù)庫(kù)的角色

組件之間就最好再也不要做數(shù)據(jù)的傳遞,組件要執(zhí)行渲染的sate統(tǒng)一從Redux的store中獲取.
這一步思考方法的改變是極為重要的.

如果一個(gè)流程的過(guò)程非常的復(fù)雜涂召,我們應(yīng)該怎么來(lái)處理果正?

這一點(diǎn)其實(shí)有很多的解決辦法,但是Redux-saga基本算是非常優(yōu)秀的解決辦法,嚴(yán)格貫徹了函數(shù)流式編程的思想,把一個(gè)復(fù)雜邏輯處理為一個(gè)數(shù)據(jù)流.

Redux-saga就是我們的救世主

redux-saga把我們上面的所有登錄的流程可以寫到一個(gè)工作流里面,香腸機(jī)器的組裝

 //login.saga.js
 import {loginReuest loginFetching,loginSuccess,loginError } from '../actions/login';
 //請(qǐng)求登錄的數(shù)據(jù)流過(guò)程
export function* loginRequestFlow(submit_info) {
  try {
    yield put(loginFetching(isFetching:true))
     const userInfoFromRemoteService = yield call(request,submit_info,'get');
    yield put(loginSuccess(userInfoFromRemoteService));
    const errorMessage = articleList.showapi_res_error;
    if (errorMessage && errorMessage !== '') {
      yield toastShort(errorMessage);
    }
  } catch (error) {
    yield put(loginSuccess([]));
    toastShort('網(wǎng)絡(luò)發(fā)生錯(cuò)誤舱卡,請(qǐng)重試');
  }
}

export function* watchuserLoginRequest(sumbit_info) {
  while (true) {
    const {
      sumbit_info
    } = yield take(types.loginRequest);
    yield fork(loginRequestFlow, );
  }
}


//login.action.js
export function userLoginRequest(sumbit_info){
   return {
     types.loginRequest,
     sumbit_info
   }
}
 
Redux-saga把登錄的流程變?yōu)橐粋€(gè)函數(shù)流操作,所有有關(guān)的操作都在這里面實(shí)現(xiàn)
Redux-saga把登錄的流程變?yōu)橐粋€(gè)函數(shù)流操作,所有有關(guān)的操作都在這里面實(shí)現(xiàn)

Redux會(huì)監(jiān)視這個(gè)數(shù)據(jù)流的觸發(fā)

Redux-saga通過(guò)監(jiān)控特定的ActionType來(lái)觸發(fā)操作
Redux-saga通過(guò)監(jiān)控特定的ActionType來(lái)觸發(fā)操作

Redux saga 暴露了幾個(gè)方法矫钓,稱為 Effects赵辕,定義如下:

Fork 執(zhí)行一個(gè)非阻塞操作。

Take 暫停并等待action到達(dá)还惠。

Race 同步執(zhí)行多個(gè) effect蚕键,然后一旦有一個(gè)完成锣光,取消其他 effect铝耻。

Call 調(diào)用一個(gè)函數(shù)瓢捉,如果這個(gè)函數(shù)返回一個(gè) promise 泡态,那么它會(huì)阻塞 saga,直到promise成功被處理状答。

Put 觸發(fā)一個(gè)Action。

Select 啟動(dòng)一個(gè)選擇函數(shù)亮钦,從 state 中獲取數(shù)據(jù)充活。

takeLatest 意味著我們將執(zhí)行所有操作混卵,然后返回最后一個(gè)(the latest one)調(diào)用的結(jié)果幕随。如果我們觸發(fā)了多個(gè)時(shí)間,它只關(guān)注最后一個(gè)(the latest one)返回的結(jié)果睦霎。

takeEvery會(huì)返回所有已出發(fā)的調(diào)用的結(jié)果走诞。

Redux-saga并沒有改變Redux對(duì)于state的處理,只不過(guò)借用了es6/es7的方法對(duì)一個(gè)相關(guān)流程的changeState函數(shù)進(jìn)行了包裝而已.

所以理解Redux-saga的工作原理,對(duì)于React和Redux工作原理理解是前提.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碑幅,一起剝皮案震驚了整個(gè)濱河市塞绿,隨后出現(xiàn)的幾起案子位隶,更是在濱河造成了極大的恐慌,老刑警劉巖篮昧,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懊昨,死亡現(xiàn)場(chǎng)離奇詭異春宣,居然都是意外死亡月帝,警方通過(guò)查閱死者的電腦和手機(jī)嚷辅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門扁位,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)域仇,“玉大人寺擂,你說(shuō)我怎么就攤上這事“惚埃” “怎么了沐鼠?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵饲梭,是天一觀的道長(zhǎng)憔涉。 經(jīng)常有香客問我兜叨,道長(zhǎng)衩侥,這世上最難降的妖魔是什么茫死? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任屡久,我火速辦了婚禮被环,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛤售。我一直安慰自己,他們只是感情好雳灾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布谎亩。 她就那樣靜靜地躺著,像睡著了一般夫凸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衷咽,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天鸽扁,我揣著相機(jī)與錄音,去河邊找鬼镶骗。 笑死桶现,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鼎姊。 我是一名探鬼主播骡和,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼相寇!你這毒婦竟也來(lái)了慰于?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤裆赵,失蹤者是張志新(化名)和其女友劉穎东囚,沒想到半個(gè)月后页藻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體楣导,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驮宴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年迎罗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窗怒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荸镊,到底是詐尸還是另有隱情岭洲,我是刑警寧澤替蔬,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布格嗅,位于F島的核電站,受9級(jí)特大地震影響贴铜,放射性物質(zhì)發(fā)生泄漏轩褐。R本人自食惡果不足惜拗踢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦好乐、人聲如沸临庇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)司草。三九已至,卻和暖如春爬泥,著一層夾襖步出監(jiān)牢的瞬間踩官,已是汗流浹背境输。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親痴柔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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