摘要:就是應(yīng)用程序領(lǐng)域的狀態(tài),它是類型中的模型的設(shè)計(jì)的概念,這設(shè)計(jì)是由架構(gòu)而來(lái)的,在原本的架構(gòu)中是允許多個(gè)的結(jié)構(gòu),簡(jiǎn)化為只有單一個(gè)。的設(shè)計(jì)中是與中的相比,它們之間有一些類似的設(shè)計(jì)。
Redux里的強(qiáng)硬規(guī)則與設(shè)計(jì)不少,大部份都會(huì)與FP(函數(shù)式程序開(kāi)發(fā))、改進(jìn)原本的Flux架構(gòu)設(shè)計(jì)有關(guān)。Redux官網(wǎng)文檔上的三大基本原則,主要是因?yàn)橛锌赡芘鲁鯇W(xué)者不理解Redux中的一些限制或設(shè)計(jì),所以先寫出來(lái)說(shuō)明,這里面也說(shuō)明了Redux的設(shè)計(jì)原理基礎(chǔ)是如何,所以強(qiáng)烈建議所有的初學(xué)者一定要徹底地理解這三大原則中的意義,多看幾遍,對(duì)日后的學(xué)習(xí)會(huì)很有幫助。以下分別說(shuō)明,主要以原文的標(biāo)題與內(nèi)容說(shuō)明,盡可以說(shuō)明的比較清楚些。
單一真相來(lái)源你的整個(gè)應(yīng)用中的state(狀態(tài)),會(huì)存儲(chǔ)在單一個(gè)store(存儲(chǔ))之中的一個(gè)對(duì)象樹(shù)狀結(jié)構(gòu)里。
Redux中只有用單一個(gè)對(duì)象大樹(shù)結(jié)構(gòu)來(lái)的存儲(chǔ)整個(gè)應(yīng)用的狀態(tài),也就是整個(gè)應(yīng)用中會(huì)用到的數(shù)據(jù),稱之為store(存儲(chǔ))。但要注意的是store(存儲(chǔ))并不是只有單純的數(shù)據(jù)而已。store就是應(yīng)用程序領(lǐng)域的狀態(tài),它是類型MVC中的Model(模型的)設(shè)計(jì)的概念,這設(shè)計(jì)是由Flux架構(gòu)而來(lái)的,在原本的Flux架構(gòu)中是允許多個(gè)store的結(jié)構(gòu),Redux簡(jiǎn)化為只有單一個(gè)。
Redux的單一個(gè)store的設(shè)計(jì)有一些好處,對(duì)開(kāi)發(fā)者來(lái)說(shuō),它可以容易調(diào)試與觀察狀態(tài)的變化,狀態(tài)存儲(chǔ)于對(duì)象樹(shù)狀結(jié)構(gòu)中,也很容易作到重作/復(fù)原(Undo/Redo)的功能。因?yàn)橹挥幸粋€(gè)store,但如果store里要儲(chǔ)放多個(gè)不同的狀態(tài)對(duì)象,以及每次的更動(dòng)數(shù)據(jù),自然就會(huì)變成了對(duì)象樹(shù)狀結(jié)構(gòu)(object tree)。
此外,如果你想要從store中取出目前的狀態(tài)數(shù)據(jù),可以用store的getState()方法。
狀態(tài)是唯讀的唯一能更動(dòng)狀態(tài)的是發(fā)送一個(gè)action(動(dòng)作),action是一個(gè)描述"發(fā)生了什么事"的純對(duì)象
這里指的"狀態(tài)",是上面說(shuō)的儲(chǔ)放在store中的狀態(tài)數(shù)據(jù),你"不能直接"對(duì)其中的狀態(tài)數(shù)據(jù)更動(dòng),只能"間接"地作這事。這與原先的React中的state與setState的概念有點(diǎn)像,Redux的意思是你不能直接更動(dòng)store里面所記錄的狀態(tài)值,只能"間接"地透過(guò)發(fā)送action對(duì)象來(lái)叫store更動(dòng)狀態(tài)。"間接"地更動(dòng)狀態(tài)是一個(gè)很關(guān)鍵的設(shè)計(jì),這是Flux中單向數(shù)據(jù)流的重點(diǎn)之一,這對(duì)于每個(gè)動(dòng)作發(fā)生,最終會(huì)影響到什么狀態(tài)上的更動(dòng),一個(gè)接一個(gè)的順序等等的一種嚴(yán)格的設(shè)計(jì)。
你可能會(huì)認(rèn)為"狀態(tài)既然是唯讀",直接與間接有什么差異,"唯讀"不就代表完全不能更動(dòng),這語(yǔ)句是不是有誤?
"唯讀"當(dāng)然就是完全不能更動(dòng)的意思沒(méi)錯(cuò),所以狀態(tài)對(duì)象的更動(dòng)是并不是在原先的狀態(tài)對(duì)象上變動(dòng)它,而是由原先狀態(tài)對(duì)象因?yàn)閯?dòng)作的加入后,產(chǎn)生一個(gè)全新的狀態(tài)對(duì)象,用這全新的狀態(tài)對(duì)象來(lái)取代原先的狀態(tài)對(duì)象而已。這在真實(shí)世界中或許很難拿比喻來(lái)說(shuō)明,但在軟體世界中這很可以很容易達(dá)成。
"發(fā)生了什么事"這句,是代表每個(gè)action都會(huì)有一個(gè)type(類型),代表這個(gè)動(dòng)作是要作什么用的,或是現(xiàn)在是發(fā)生了什么,例如是要新建一筆什么數(shù)據(jù),或是刪除整個(gè)數(shù)據(jù)等等,動(dòng)作對(duì)象除了要說(shuō)明它是要作什么之外,也需要包含所影響的數(shù)據(jù)。
發(fā)送一個(gè)action(動(dòng)作),使用的是store.dispatch(action)語(yǔ)法樣式,下面這個(gè)例子就是一個(gè)要更動(dòng)狀態(tài)的代碼:
store.dispatch({ type: "COMPLETE_TODO", index: 1 })
中間的那個(gè)純對(duì)象,就叫作action(動(dòng)作),它是一個(gè)單純用于描述發(fā)生了什么事與相關(guān)數(shù)據(jù)的純對(duì)象:
{ type: "COMPLETE_TODO", index: 1 }
還記得我們?cè)赗eact中的state與setState方法的設(shè)計(jì)嗎?state也是不能直接更動(dòng)的,一定要透過(guò)setState方法才能更動(dòng)它。那這是為什么呢?因?yàn)?b>setState不光只是更動(dòng)state值,它還要作重新渲染的動(dòng)作,React需要比對(duì)目前的狀態(tài),與即將要變動(dòng)的狀態(tài),這樣才能進(jìn)移動(dòng)新渲染的工作。Redux的設(shè)計(jì)中store是與React中的state相比,它們之間有一些類似的設(shè)計(jì)。
更動(dòng)只能由純函數(shù)來(lái)進(jìn)行要指示狀態(tài)樹(shù)要如何依actions(動(dòng)作)來(lái)作改變,你需要撰寫純粹的歸納函數(shù)(reducers)
Redux中的reducer的原型會(huì)長(zhǎng)得像下面這樣,你可以把它當(dāng)作就是 之前的狀態(tài) + 動(dòng)作 = 新的狀態(tài) 的公式:
(previousState, action) => newState
注: 你可以參考Redux中Reducers這一章的內(nèi)容,里面有實(shí)例。
不過(guò),Redux中的reducer一定是純函數(shù)(pure function),也就是不能有副作用的函數(shù)。因此由reducer所產(chǎn)生的新?tīng)顟B(tài),并不是直接修改之前的狀態(tài)而來(lái),而是一個(gè)復(fù)制之前狀態(tài),然后加上動(dòng)作改變的部份,產(chǎn)生的一個(gè)新的對(duì)象,它這樣設(shè)計(jì)是有原因的。
Redux的store設(shè)計(jì),并不是原本Flux架構(gòu)中的store,而是ReduceStore,這個(gè)ReduceStore是一個(gè)在Flux中的store進(jìn)化版本,在說(shuō)明中它有一個(gè)叫作reduce的方法,說(shuō)明如下:
reduce(state: T, action: Object): T 歸納(Reduces)目前的state(狀態(tài))與一個(gè)action(動(dòng)作)到新的store中的state(狀態(tài))。所有的子類都需要實(shí)作這個(gè)方法。這個(gè)方法必須是純粹而是無(wú)副作用。
那為何要用這個(gè)進(jìn)化的ReduceStore?它最后有說(shuō)明一段:
不需要發(fā)送更動(dòng)事件注意所有繼承自ReduceStore的store,不需要手動(dòng)發(fā)送在reduce()中的更動(dòng)事件...state(狀態(tài))會(huì)自動(dòng)地比對(duì)在每個(gè)dispatch(發(fā)送)之前與之后,與自動(dòng)地作發(fā)送更動(dòng)事件...
ReduceStore的設(shè)計(jì)與Redux最一開(kāi)始的版本差不多是同時(shí)間發(fā)布的,在開(kāi)發(fā)者之間彼此有交流。Redux的store運(yùn)用了類似于ReduceStore的設(shè)計(jì),所以要更動(dòng)Redux中的store,需要透過(guò)reducer,這是為了簡(jiǎn)化原本在Flux數(shù)據(jù)流的實(shí)作流程。
reducer在Redux中扮演了十分重要的關(guān)鍵角色,它是一種對(duì)store中所存放的狀態(tài),要如何因應(yīng)不同的動(dòng)作而進(jìn)行刷新的函數(shù),而store也是由reducer所創(chuàng)建,例如像下面的代碼:
// @Reducer // // action payload = action.text // 使用純粹函數(shù)的數(shù)組unshift,不能有副作用 // state(狀態(tài))一開(kāi)始的值是空數(shù)組`state=[]` function todoApp(state = [], action) { switch (action.type) { case "ADD_ITEM": return [action.text, ...state] default: return state } } // @Store // // 由reducer創(chuàng)建store const store = createStore(todoApp)
針對(duì)應(yīng)用中不同功能的狀態(tài),可以分別寫出不同的reducer,Redux中提供了combineReducers函數(shù)可以合并多個(gè)reducer,例如以下的代碼:
function todos(state = [], action) { switch (action.type) { case "ADD_TODO": return state.concat([ action.text ]) default: return state } } function counter(state = 0, action) { switch (action.type) { case "INCREMENT": return state + 1 case "DECREMENT": return state - 1 default: return state } } // rootReducer是個(gè)組合過(guò)的函數(shù), // 這里用的是對(duì)象屬性初始設(shè)置簡(jiǎn)寫法, // combineReducers傳參是一個(gè)對(duì)象 const rootReducer = combineReducers({ todos, counter })
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/81350.html
摘要:系列文章入門本文進(jìn)階番外篇狀態(tài)管理,第一次聽(tīng)到這個(gè)詞要追溯到去年年底。只讀的唯一改變的方法就是觸發(fā),是一個(gè)用于描述已發(fā)生事件的普通對(duì)象。沒(méi)有特殊情況沒(méi)有副作用,沒(méi)有請(qǐng)求沒(méi)有變量修改,只進(jìn)行單純執(zhí)行計(jì)算。 系列文章: Redux 入門(本文) Redux 進(jìn)階 番外篇: Vuex — The core of Vue application 狀態(tài)管理,第一次聽(tīng)到這個(gè)詞要追溯到去年年...
摘要:接下來(lái)筆者就從源碼中探尋是如何實(shí)現(xiàn)的。其實(shí)很簡(jiǎn)單,可以簡(jiǎn)單理解為一個(gè)約束了特定規(guī)則并且包括了一些特殊概念的的發(fā)布訂閱器。新舊中存在的任何都將收到先前的狀態(tài)。這有效地使用來(lái)自舊狀態(tài)樹(shù)的任何相關(guān)數(shù)據(jù)填充新?tīng)顟B(tài)樹(shù)。 Redux是當(dāng)今比較流行的狀態(tài)管理庫(kù),它不依賴于任何的框架,并且配合著react-redux的使用,Redux在很多公司的React項(xiàng)目中起到了舉足輕重的作用。接下來(lái)筆者就從源碼...
摘要:只要是同樣的輸入,必定得到同樣的輸出。純函數(shù)是函數(shù)式編程的概念,必須遵守以下一些約束。中的概念執(zhí)行的動(dòng)作,包括動(dòng)作所需要的數(shù)據(jù),改變數(shù)據(jù)的唯一來(lái)源,一般是通過(guò)將傳到。只是描述了有事情發(fā)生了這一事實(shí),并沒(méi)有指明應(yīng)用如何更新。 1.什么是Redux 管理Web應(yīng)用全局狀態(tài)的框架。 單頁(yè)面應(yīng)用,顧名思義,和傳統(tǒng)項(xiàng)目的最明顯區(qū)別就是項(xiàng)目只有一個(gè)頁(yè)面,頁(yè)面有一個(gè)根元素,我們寫的每一個(gè)頁(yè)面是一個(gè)大...
摘要:簡(jiǎn)介創(chuàng)建的函數(shù),返回一個(gè)對(duì)象,包含等方法合并多個(gè)中間件處理,在實(shí)際的前調(diào)用一系列中間件,類似于綁定和函數(shù)式編程中常見(jiàn)的方法,介紹官方提供的綁定庫(kù)。 前言 在學(xué)習(xí)了React之后, 緊跟著而來(lái)的就是Redux了~ 在系統(tǒng)性的學(xué)習(xí)一個(gè)東西的時(shí)候, 了解其背景、設(shè)計(jì)以及解決了什么問(wèn)題都是非常必要的。接下來(lái)記錄的是, 我個(gè)人在學(xué)習(xí)Redux時(shí)的一些雜七雜八~ Redux是什么 通俗理解 h...
摘要:是一個(gè)程序架構(gòu),源于提出的一種架構(gòu),然而,它不僅可以應(yīng)用于,還可以應(yīng)用于其他任何框架中。有以下職責(zé)維持應(yīng)用的提供方法獲取提供方法更新通過(guò)注冊(cè)監(jiān)聽(tīng)器通過(guò)返回的函數(shù)注銷監(jiān)聽(tīng)器。同時(shí),的返回值實(shí)際上是一個(gè)函數(shù)可以解除監(jiān)聽(tīng)。 Redux是一個(gè)程序架構(gòu),源于Flux(Facebook提出的一種架構(gòu)),然而,它不僅可以應(yīng)用于React,還可以應(yīng)用于其他任何框架中。值得一提的是,Redux的源代碼很...
閱讀 1644·2021-11-16 11:44
閱讀 3362·2021-09-29 09:43
閱讀 685·2019-08-30 10:52
閱讀 1003·2019-08-29 11:01
閱讀 3314·2019-08-26 11:47
閱讀 2986·2019-08-23 12:18
閱讀 1419·2019-08-22 17:04
閱讀 2106·2019-08-21 17:04