Java深度學習,目前對redux,redux-saga最通俗的解釋


最近在學習react全家桶,於是做了一個基於react-pdf的在線pdf閱讀項目,項目地址:

yjf27281181/react-readme​github.com

裡面一些異步操作(登錄,查詢數據庫等)參考了另外一個博客項目的異步操作,由於之前沒有接觸過react,猛然看到如此紛繁複雜的處理流程實屬懵逼,在知乎也看了不少大牛的文章,但還是覺得通俗性差了一丁點火候,正好趁機會記錄一下我對redux和redux-saga的理解。

一、為什麼要用redux

每一個工具的出現都是為了解決某一個痛點,react的痛點就是繁瑣的props和state操作,舉個例子:A主頁下有個工具欄B,工具欄B下有個按鈕,按鈕可以更新控件D,但只能通過A->C->D,這個時候如果想要點擊B下的按鈕更新D,需要將數據作為props從A傳到C傳到D,然後再在A中寫一個函數用來更新這個state,然後把這個函數作為props傳入B,作為按鈕的點擊事件。

由於操作實在過於複雜,你想到能不能直接在B中修改D的state呢?於是redux就誕生了,當然,redux並不是讓你能從B組件直接更改D的state,而是通過更改公共state,改完之後再通知D去更新state。下面舉個例子說明這個過程。

二、通俗易懂的例子

那麼什麼是公共state,如何修改公共state呢?到這裡,你在別的地方應該已經看到了什麼action,純函數,reducer之類的東西了,如果你還是不懂,請看下面這個例子。

假設你(組件B)的銀行賬戶上有500元(公共state),你想將其中的100元轉到別的地方(比如支付寶),且你和你的女朋友(組件D)同時訂閱了這個賬戶的短信提醒。這時,你是不可能直接去銀行然後操作銀行電腦進行轉錢的(不能直接修改公共state),假設你由於感冒了不能說話,於是你只能走到櫃檯前,遞給操作員(reducer)一個條子(action),寫著:

操作類型:轉賬

金額: 100

目的地:支付寶

你把這個字條遞給操作員,然後操作員開始更新你的餘額,更新完成之後短信提醒你和你的女朋友state已經更新了,然後你的女朋友就知道你的餘額從500變成400了。

三、例子代碼化

那麼如何用代碼實現這個流程呢?

首先我們來看銀行的工作,銀行就是reducer,它能支持各種各樣的操作(action),現在我們把這個操作寫出來。

bankReducer.js

export const actionTypes = {

轉賬: "轉賬",

存錢: "存錢",

取錢:"取錢"

}

const initialState = {

餘額: 500

};

現在我們有了三個操作,分別是轉賬,存錢和取錢,然後我們需要定義一個reducer函數,來告訴操作員當遇到這些actionType的時候分別做什麼處理

export function reducer(state = 初始值, 操作) {

switch (操作.type) {

case actionTypes.存錢:

return {

餘額: state.餘額+action.存入金額

};

case actionTypes.取錢:

return {

餘額: state.餘額-action.取出金額

},

case actionTypes.轉賬:

return {

餘額: state.餘額-action.轉賬金額

};

}

現在,當操作員拿到用戶遞過來的紙條的時候就能進行相應的操作了,但是用戶能進行什麼樣的操作呢?於是銀行還應該提供一些接口,告訴用戶可以進行哪些操作:

export const actions = {

存錢_操作: function(存入金額) {

return {

type: actionTypes.存錢,

存入金額

};

},

取錢_操作: function(取出金額) {

return {

type: actionTypes.取錢,

取出金額

};

},

轉賬_操作: function(轉賬金額) {

return {

type: actionTypes.轉賬,

轉賬金額

};

},

}

讓我們再重新梳理一下整個流程,用戶首先填寫信息到action,你可以理解為用戶寫了一個小紙條,比如轉賬,那麼用戶可以這樣調用:

轉賬_操作(100)

那麼function生成的小紙條就是

{

type: actionType.轉賬,

100

}

然後這個小紙條就會自動遞給操作員(reducer,是的,你不用管是怎麼給reducer的),然後操作員看到這個action的type是轉賬,那麼進入轉賬操作:

case actionTypes.轉賬:

return {

...state,

餘額: state.餘額-action.轉賬金額

};

這時,你的餘額就更新為400了。

好了,現在整個銀行都完成了,我們來看用戶的部分,也就是你

you.jsx

首先我們需要一個按鈕,按一下就轉賬100,怎麼實現呢?

class You extends Component {

constructor(props) {

super(props);

this.state = {

餘額: 0

};

}

onClick = (e)=>{

//點擊之後進行轉賬

}

render() {

return

}

}

有人可能會問,為什麼這裡餘額是0?因為餘額需要銀行統一通知,而不是自己設置的,那麼現在就與要把你和銀行連接起來,使得你能將小紙條遞給操作員,也能收到銀行的消息:

於是你就能看到之前頭疼的兩個函數了:mapStateToProps和mapDispatchToProps,那這兩個函數作用是什麼呢?

mapStateToProps:將銀行的state更新到本地

mapDispatchToProps: 讓你能使用銀行提供的操作接口

先說mapStateToProps,我們現在state中只有“餘額”這一個屬性,但是實際上公共state中可能有很多其他的屬性,比如

const initialState = {

餘額: 500,

行長姓名: 顏小四,

銀行地址: 佐家壟職業技術學院旁的螺獅粉店裡,

...

};

這些信息可能其他組件關係,但是你並不關心,所以當你更新本地state的時候,只需要更新餘額就行了

function mapStateToProps(state) {

return {

餘額: state.餘額,

};

}

這個函數的意思是,當我賬戶中餘額屬性更新時,同步到我的組件屬性裡(想要更新UI,需要調用componentWillReceiveProps,並在裡面調用setState)

同樣,銀行可能提供很多操作,但是我只關心“轉賬”操作,於是可以只將轉賬操作映射過來,然後“我要轉賬”會作為函數,存在this.props裡,調用方式為this.props.我要轉賬(注意這個函數的參數是與銀行中的action參數一致的,轉賬操作的參數為“轉賬金額”):

import { actions as bankActions } from "bank.js";

function mapDispatchToProps(dispatch) {

return {

我要轉賬: bindActionCreators(bankActions.轉賬_操作, dispatch),

};

現在,準備工作完了,將你和銀行連接即可

export default connect(

mapStateToProps,

mapDispatchToProps

)(You)

這樣你就成功地與銀行連接了,你能調用銀行的給出的接口了。現在,如果我們就能寫onClick函數了,點擊之後寫入小紙條(action),紙條會自動交給操作員(reducer)更改你的餘額(state)。

onClick = (e)=> {

this.props.我要轉賬(100) //填寫轉賬小紙條,寫入轉出金額為100

}

現在你已經能操作銀行了,那怎麼讓女朋友也接受到通知呢?首先我們定義女友這個組件:

notExist.jsx

class notExist extends Component {

constructor(props) {

super(props);

this.state = {

餘額: 0

};

}

render() {

return

{this.state.餘額}

}

function mapStateToProps(state) {

return {

餘額: state.餘額,

};

}

export default connect(

mapStateToProps,

)(notExist)

}

可以看到,我們只需要寫好mapStateToProps, 並且connect到銀行,那麼你的女友就能收到通知了

結束語

感覺寫了很多了,如果反響好的話我會更新我對redux-saga的理解。

本文出自知乎

Java深度學習,目前對redux,redux-saga最通俗的解釋

更多相關內容,Java架構師,軟件開發等學習資料,電子書及視頻還有高級講師公開課免費資源

需要的可以私聊小編髮送【學習】二字


分享到:


相關文章: