亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

干貨 | React技術(shù)棧耕耘 —— Redux

LdhAndroid / 800人閱讀

摘要:作者小滬江前端開(kāi)發(fā)工程師本文為原創(chuàng)文章,有不當(dāng)之處歡迎指出。于是,單一數(shù)據(jù)源規(guī)則實(shí)施起來(lái),是規(guī)定用的頂層容器組件的來(lái)存儲(chǔ)單一對(duì)象樹(shù),同時(shí)交給來(lái)管理。顧名思義,當(dāng)更新時(shí),的回調(diào)函數(shù)會(huì)更新視圖層,以達(dá)到訂閱的效果。

作者:小boy (滬江web前端開(kāi)發(fā)工程師)
本文為原創(chuàng)文章,有不當(dāng)之處歡迎指出。轉(zhuǎn)載請(qǐng)注明出處。
文章示例代碼:https://github.com/ikcamp/rea...

Redux 是近年來(lái)提出的 Flux 思想的一種實(shí)踐方案,在它之前也有 reflux 、 fluxxor 等高質(zhì)量的作品,但短短幾個(gè)月就在 GitHub 上獲近萬(wàn) star 的成績(jī)讓這個(gè)后起之秀逐漸成為 Flux 的主流實(shí)踐方案。

正如 Redux 官方所稱,React 禁止在視圖層直接操作 DOM 和異步行為 ( removing both asynchrony and direct DOM manipulation ),來(lái)拆開(kāi)異步和變化這一對(duì)冤家。但它依然把狀態(tài)的管理交到了我們手中。Redux 就是我們的狀態(tài)管理小管家。

安利的話先暫時(shí)說(shuō)到這,本期的技術(shù)周刊將為你帶來(lái) React-Redux 在滬江前端團(tuán)隊(duì)中的實(shí)踐。

0. 放棄

你沒(méi)有看錯(cuò),在開(kāi)始之前我們首先談?wù)撘幌率裁辞闆r下不應(yīng)該用 Redux。
所謂殺雞焉用宰牛刀,任何技術(shù)方案都有其適用場(chǎng)景。作為一個(gè)思想的實(shí)踐方案,Redux 必然會(huì)為實(shí)現(xiàn)思想立規(guī)矩、鋪基礎(chǔ),放在復(fù)雜的 React 應(yīng)用里,它會(huì)是“金科玉律”,而放在結(jié)構(gòu)不算復(fù)雜的應(yīng)用中,它只會(huì)是“繁文縟節(jié)”。

如果我們將要構(gòu)建的應(yīng)用無(wú)需多層組件嵌套,狀態(tài)變化簡(jiǎn)單,數(shù)據(jù)單一,那么就應(yīng)放棄 Redux ,選用單純的 React 庫(kù) 或其他 MV* 庫(kù)。畢竟,沒(méi)有人愿意雇傭一個(gè)收費(fèi)比自己收入還高的財(cái)務(wù)顧問(wèn)。

1. 思路

首先,我們回顧一下 Redux 的基本思路

當(dāng)用戶與界面交互時(shí),交互事件的回調(diào)函數(shù)會(huì)觸發(fā) ActionCreators ,它是一個(gè)函數(shù),返回一個(gè)對(duì)象,該對(duì)象攜帶了用戶的動(dòng)作類型和修改 Model 必需的數(shù)據(jù),這個(gè)對(duì)象也被我們稱作 Action 。

以 TodoList 為例,添加一個(gè) Todo 項(xiàng)的 ActionCreator 函數(shù)如下所示:

在上例中,addTodo 就是 ActionCreator 函數(shù),該函數(shù)返回的對(duì)象就是 Action 。

其中 type 為 Redux 中約定的必填屬性,它的作用稍后我們會(huì)講到。而 text 則是執(zhí)行 “添加 Todo 項(xiàng)“ 這個(gè)動(dòng)作必需的數(shù)據(jù)。

當(dāng)然,不同動(dòng)作所需要的數(shù)據(jù)也不盡相同,如 “刪除Todo” 動(dòng)作,我們就需要知道 todo 項(xiàng)的 id,“拉取已有的Todo項(xiàng)” 動(dòng)作,我們就需要傳入一個(gè)元素為 Todo 項(xiàng)對(duì)象的數(shù)組( todos )。形如 text 、 id 、 todos 這類屬性,我們習(xí)慣稱呼其為 “ payload ” 。

現(xiàn)在,我們得到了一個(gè) “栩栩如生” 的動(dòng)作。它足夠簡(jiǎn)潔,但擔(dān)任 Model 的 store 暫時(shí)還不知道如何感知這個(gè)動(dòng)作從而改變數(shù)據(jù)結(jié)構(gòu)。

為了處理這個(gè)關(guān)鍵問(wèn)題,Reducer 巧然登場(chǎng)。它仍然是一個(gè)函數(shù),而且是沒(méi)有副作用的純函數(shù)。它只接收兩個(gè)參數(shù):state 和 action ,返回一個(gè) newState 。

沒(méi)錯(cuò),state 就是你在 React 中熟知的 state,但根據(jù) Redux 三原則 之一的 “單一數(shù)據(jù)源” 原則,Reducer 幽幽地說(shuō):“你的 state 被我承包了。”

于是,單一數(shù)據(jù)源規(guī)則實(shí)施起來(lái),是規(guī)定用 React 的頂層容器組件( Container Components )的 state 來(lái)存儲(chǔ)單一對(duì)象樹(shù),同時(shí)交給 Redux store 來(lái)管理。

這里區(qū)分一下 state 和 Redux store:state 是真正儲(chǔ)存數(shù)據(jù)的對(duì)象樹(shù),而 Redux store 是協(xié)調(diào) Reducer、state、Action 三者的調(diào)度中心。

而如此前所說(shuō),Reducer 此時(shí)手握兩個(gè)關(guān)鍵信息:舊的數(shù)據(jù)結(jié)構(gòu)(state),還有改變它所需要的信息 (action),然后聰明的 Reducer 算盤一敲,就能給出一個(gè)新的 state ,從而更新數(shù)據(jù),響應(yīng)用戶。下面依然拿 TodoList 舉例:

當(dāng)接收到一個(gè) action 時(shí),Reducer 從 action.type 識(shí)別出該動(dòng)作是要添加 Todo 項(xiàng),然后路由到相應(yīng)的處理方案,接著根據(jù) action.text 完成了處理,返回一個(gè) newState 。過(guò)程之間,整個(gè)應(yīng)用的 state 就從 state => newState 完成了狀態(tài)的變更。

這個(gè)過(guò)程讓我們很自然地聯(lián)想到去銀行存取錢的經(jīng)歷,顯然我們應(yīng)該告訴柜臺(tái)操作員要存取錢,而不是遙望著銀行的金庫(kù)自言自語(yǔ)。

Reducer 為我們梳理了所有變更 state 的方式,那么 Redux store 從無(wú)到有,從有到變都應(yīng)該與 Reducer 強(qiáng)關(guān)聯(lián)。

因此,Redux 提供了 createStore 函數(shù),他的第一個(gè)參數(shù)就是 Reducer ,用以描繪 state 的更改方式。第二個(gè)是可選參數(shù) initialState ,此前我們知道,這個(gè) initialState 參數(shù)也可以傳給 Reducer 函數(shù)。放在這里做可選參數(shù)的原因是為同構(gòu)應(yīng)用提供便捷。

createStore 函數(shù)最終返回一個(gè)對(duì)象,也就是我們所說(shuō)的 store 對(duì)象。主要提供三個(gè)方法: getState、dispatch subscribe。 其中 getState() 獲得 state 對(duì)象樹(shù)。dispatch(actionCreator) 用以執(zhí)行 actionCreators,建起從 action 到 store 的橋梁。

僅僅完成狀態(tài)的變更可不算完,我們還得讓視圖層跟上 store 的變化,于是 Redux 還為 store 設(shè)計(jì)了 subscribe 方法。顧名思義,當(dāng) store 更新時(shí),store.subscribe() 的回調(diào)函數(shù)會(huì)更新視圖層,以達(dá)到 “訂閱” 的效果。

在 React 中,有 react-redux 這樣的橋接庫(kù)為 Redux 的融入鋪平道路。所以,我們只需為頂層容器組件外包一層 Provider 組件、再配合 connect 函數(shù)處理從 store 變更到 view 渲染的相關(guān)過(guò)程。

而頂層容器組件往下的子組件只需憑借 props 就能一層層地拿到 store 數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)了。就像這樣:

至此,我們走了一圈完整的數(shù)據(jù)流。然而,在實(shí)際項(xiàng)目中,我們面臨的需求更為復(fù)雜,與此同時(shí),redux 和 react 又是具有強(qiáng)大擴(kuò)展性的庫(kù),接下來(lái)我們將結(jié)合以上的主體思路,談?wù)勎覀冊(cè)趯?shí)際開(kāi)發(fā)中會(huì)遇到的一些細(xì)節(jié)問(wèn)題。

2. 細(xì)節(jié) 應(yīng)用目錄

清晰的思路須輔以分工明確的文件模塊,才能讓我們的應(yīng)用達(dá)到更佳的實(shí)踐效果,同時(shí),統(tǒng)一的結(jié)構(gòu)也便于腳手架生成模板,提高開(kāi)發(fā)效率。

以下的目錄結(jié)構(gòu)為團(tuán)隊(duì)伙伴多次探討和改進(jìn)而來(lái)(限于篇幅,這里只關(guān)注 React 應(yīng)用的目錄。):

入口文件 app.js 與頂層組件 react/container.js

這塊我們基本上保持和之前思路上的一致,用 react-redux 橋接庫(kù)提供的 Provider 與函數(shù) connect 完成 Redux store 到 React state 的轉(zhuǎn)變。

細(xì)心的你會(huì)在 Provider 的源碼中發(fā)現(xiàn),它最終返回的還是子組件(本例中就是頂層容器組件 “Container“ )。星星還是那個(gè)星星,Container 還是那個(gè) Container,只是多了一個(gè) Redux store 對(duì)象。

而 Contaier 作為 業(yè)務(wù)組件 Wrapper 的 高階組件 ,負(fù)責(zé)把 Provider 賦予它的 store 通過(guò) store.getState() 獲取數(shù)據(jù),轉(zhuǎn)而賦值給 state 。然后又根據(jù)我們定義的 mapStateToProps 函數(shù)按一定的結(jié)構(gòu)將 state 對(duì)接到 props 上。 mapStateToProps 函數(shù)我們稍后詳說(shuō)。如下所見(jiàn),這一步主要是 connect 函數(shù)干的活兒。

業(yè)務(wù)組件 component/Wrapper.js 與 mapStateToProps

這兩個(gè)模塊是整個(gè)應(yīng)用很重要的業(yè)務(wù)模塊。作為一個(gè)復(fù)雜應(yīng)用,將 state 上的數(shù)據(jù)和 actionCreator 合理地分發(fā)到各個(gè)業(yè)務(wù)組件中,同時(shí)要易于維護(hù),是開(kāi)發(fā)的關(guān)鍵。

首先,我們?cè)O(shè)計(jì) mapStateToProps 函數(shù)。需要謹(jǐn)記一點(diǎn): 拿到的參數(shù)是 connect 函數(shù)交給我們的根 state,返回的對(duì)象是最終 this.props 的結(jié)構(gòu)。

和 Redux 官方示例不同的是,我們?yōu)榱丝勺x性,將分發(fā) action 的函數(shù)也囊括進(jìn)這個(gè)結(jié)構(gòu)中。這也是得益于 bindActions 模塊,稍后我們會(huì)講到。

這樣,我們這個(gè)函數(shù)就準(zhǔn)備好履行它分發(fā)數(shù)據(jù)和組件行為的職責(zé)了。那么,它又該如何 “服役” 呢?

敏銳的你一定察覺(jué)到剛才我們?cè)O(shè)計(jì)的結(jié)構(gòu)中,以 “ params ” 開(kāi)頭的屬性既沒(méi)起到給組件展示數(shù)據(jù)的作用,又沒(méi)有為組件發(fā)送 action 的功能。它們便是我們分發(fā)以上兩種功能屬性的關(guān)鍵。

我們先來(lái)看看業(yè)務(wù)組件 Wrapper :

現(xiàn)在,param 屬性們?yōu)槲覀冋故玖怂缪莸慕巧涸诮M件中實(shí)際分發(fā)數(shù)據(jù)和方法的快遞小哥。這樣,即使項(xiàng)目越變?cè)酱?,組件嵌套越來(lái)越多,我們也能在 param.js 模塊中,清晰地看到我們的組件結(jié)構(gòu)。需求更改的時(shí)候,我們也能快速地定位和修改,而不用對(duì)著堆積如山的組件模塊梳理父子關(guān)系。

相信你應(yīng)該能猜到剩下的子組件們?cè)趺慈〉綌?shù)據(jù)了,這里限于篇幅就不貼出它們的代碼了。

Action 模塊: react/action.js、react/actionType.js 和 react/bindActions.js

在前面的介紹中,我們提到:一個(gè) ActionCreator 長(zhǎng)這樣:

而在 Redux 中,真正讓其分發(fā)一個(gè) action ,并讓 store 響應(yīng)該 action,依靠的是 dispatch 方法,即:

交互動(dòng)作一多,就會(huì)變成:

而容易想到:抽象出一個(gè)公用函數(shù)來(lái)分發(fā) action (這里粗略寫(xiě)一下我的思路,簡(jiǎn)化方式并不唯一)

而細(xì)心的 Redux 已經(jīng)為我們提供了這個(gè)方法 —— bindActionCreator
所以,我們的 bindActions.js 模塊就借用了 bindActionCreator 來(lái)簡(jiǎn)化 action 的分發(fā):

不難想象,action 模塊里就是一個(gè)個(gè) actionCreator :

為了更好地合作,我們多帶帶為 action 的 type 劃分了一個(gè)模塊

react/reducers/ 和 react/store.js

前面我們說(shuō)到,reducer 的作用就是區(qū)別 action type 然后更新 state ,這里不再贅述。可上手實(shí)際項(xiàng)目的時(shí)候,你會(huì)發(fā)現(xiàn) action 類型和對(duì)應(yīng)處理方式多起來(lái)會(huì)讓單個(gè) reducer 迅速龐大。

為此,我們就得想方設(shè)法將其按業(yè)務(wù)邏輯拆分,以免難以維護(hù)。但是如何把拆分后的 Reducer 組合起來(lái)呢 Redux 再次為我們提供便捷 —— combineReducers 。

只有單一 Reducer 時(shí),想必代碼結(jié)構(gòu)你也了然:

我們最終得到的 state 結(jié)構(gòu)是:

state

demoAPP

當(dāng)有多個(gè) reducer 時(shí):

我們最終得到的 state 結(jié)構(gòu)是:

state

demoAPP

reducerB

想必你已經(jīng)想到更進(jìn)一步,把這些 Reducer 拆分到相應(yīng)的文件模塊下:

接著,我們來(lái)看 store 模塊:

怎么和想象的不一樣?不應(yīng)該是這樣嗎:

這里引入 redux 中間件的概念,你只需知道 redux 中間件的作用就是 在 action 發(fā)出以后,給我們一個(gè)再加工 action 的機(jī)會(huì) 就可以了。

為什么要引入 redux-thunk 這個(gè)中間件呢?

要知道,我們此前所討論的都是同步過(guò)程。實(shí)際項(xiàng)目中,只要遇到請(qǐng)求接口的場(chǎng)景(當(dāng)然不只有這種場(chǎng)景)就要去處理異步過(guò)程。

前面我們知道,dispatch 一個(gè) ActionCreator 會(huì)立即返回一個(gè) action 對(duì)象,用以更新數(shù)據(jù),而中間件賦予我們?cè)偬幚?action 的機(jī)會(huì)。

試想一下,如果我們?cè)谶@個(gè)過(guò)程中,發(fā)現(xiàn) ActionCreator 返回的并不是一個(gè) action 對(duì)象,而是一個(gè)函數(shù),然后通過(guò)這個(gè)函數(shù)請(qǐng)求接口,響應(yīng)就緒后,我們?cè)?dispatch 一個(gè) ActionCreator ,這次我們真的返回一個(gè) action ,然后攜帶接口返回的數(shù)據(jù)去更新 state 。 這樣一來(lái)不就解決了我們的問(wèn)題嗎?

當(dāng)然,這只是基本思路,關(guān)于 redux 的中間件設(shè)計(jì),又是一個(gè)有趣的話題,有興趣我們可以再開(kāi)一篇專門討論,這里點(diǎn)到為止。

回到我們的話題,經(jīng)過(guò)

這樣包裝一遍 store 后,我們就可以愉快地使用異步 action 了:

這里我們用 promise 方式來(lái)處理請(qǐng)求,model.js 模塊如你所想是一些接口請(qǐng)求 promise,就像這樣:

你也可以參閱我們往期介紹的其他方式。

最后,我們?cè)賮?lái)完善一下之前的流程:

3.結(jié)語(yǔ)

Redux 的 API 一只手都能數(shù)得完,源碼更是精煉,加起來(lái)不超過(guò)500行。但它給我們帶來(lái)的,不啻是一套復(fù)雜應(yīng)用解決方案,更是 Flux 思想的精簡(jiǎn)表達(dá)。此外,你還可以從中體會(huì)到函數(shù)式編程的樂(lè)趣。

一千個(gè)觀眾心中有一千個(gè)哈姆萊特,你腦海里的又是哪一個(gè)呢?

本文示例代碼GitHub地址:https://github.com/ikcamp/rea...

參考

《Redux 官方文檔》
《深入 React 技術(shù)?!?/p>


iKcamp原創(chuàng)新書(shū)《移動(dòng)Web前端高效開(kāi)發(fā)實(shí)戰(zhàn)》已在亞馬遜、京東、當(dāng)當(dāng)開(kāi)售。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/85137.html

相關(guān)文章

  • 解析Twitter前端架構(gòu) 學(xué)習(xí)復(fù)雜場(chǎng)景數(shù)據(jù)設(shè)計(jì)

    摘要:總結(jié)本文分析了在采用架構(gòu)下的數(shù)據(jù)設(shè)計(jì)結(jié)構(gòu),在一個(gè)復(fù)雜的場(chǎng)景下,希望引起讀者對(duì)能有一個(gè)更深入的認(rèn)識(shí)。 前幾天刷Twitter,發(fā)現(xiàn)Nicolas(Engineering at @twitter. Technical Lead for Twitter Lite)發(fā)布了這么一條推文: showImg(https://segmentfault.com/img/remote/1460000009...

    csRyan 評(píng)論0 收藏0
  • React Redux 中間件思想遇見(jiàn) Web Worker 的靈感(附demo)

    摘要:寫(xiě)在最前原文首發(fā)于作者的知乎專欄中間件思想遇見(jiàn)的靈感附,感興趣的同學(xué)可以知乎關(guān)注,進(jìn)行交流。其中,最重要的一個(gè)便是對(duì)多線程的支持。在中提出了工作線程的概念,并且規(guī)范出的三大主要特征能夠長(zhǎng)時(shí)間運(yùn)行響應(yīng)理想的啟動(dòng)性能以及理想的內(nèi)存消耗。 寫(xiě)在最前 原文首發(fā)于作者的知乎專欄:React Redux 中間件思想遇見(jiàn) Web Worker 的靈感(附demo),感興趣的同學(xué)可以知乎關(guān)注,進(jìn)行交流...

    whatsns 評(píng)論0 收藏0
  • 拒絕Redux文檔“毒害” 一個(gè)項(xiàng)目告訴你Redux最新真正哲學(xué)

    摘要:之前分享過(guò)幾篇關(guān)于技術(shù)棧的原創(chuàng)文章解析前端架構(gòu)學(xué)習(xí)復(fù)雜場(chǎng)景數(shù)據(jù)設(shè)計(jì)干貨總結(jié)打造單頁(yè)應(yīng)用一個(gè)項(xiàng)目理解最前沿技術(shù)棧真諦一個(gè)工程實(shí)例今天進(jìn)一步剖析一個(gè)實(shí)際案例移動(dòng)網(wǎng)頁(yè)版。目前面臨的問(wèn)題在于提高產(chǎn)品的各方面性能體驗(yàn)。 之前分享過(guò)幾篇關(guān)于React技術(shù)棧的原創(chuàng)文章: 解析Twitter前端架構(gòu) 學(xué)習(xí)復(fù)雜場(chǎng)景數(shù)據(jù)設(shè)計(jì) React Conf 2017 干貨總結(jié)1: React + ES next ...

    YuboonaZhang 評(píng)論0 收藏0
  • React技術(shù)實(shí)現(xiàn)XXX點(diǎn)評(píng)App demo

    摘要:項(xiàng)目的架構(gòu)也是最近在各種探討研究。還求大神多指點(diǎn)項(xiàng)目技術(shù)總結(jié)技術(shù)棧項(xiàng)目結(jié)構(gòu)探究初體驗(yàn)關(guān)于項(xiàng)目中的配置說(shuō)明項(xiàng)目簡(jiǎn)單說(shuō)明開(kāi)發(fā)這一套,我個(gè)人的理解是體現(xiàn)的是代碼分層職責(zé)分離的編程思想邏輯與視圖嚴(yán)格區(qū)分。前端依舊使用技術(shù)棧完成。 項(xiàng)目地址:https://github.com/Nealyang/R...技術(shù)棧:react、react-router4.x 、 react-redux 、 webp...

    wslongchen 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<