異步 Action
通過(guò) redux-thunk ,在 action 中 dispatch action ,可以是簡(jiǎn)化異步工作流。
Middleware
它提供的是位于 action 被發(fā)起之后,到達(dá) reducer 之前的擴(kuò)展點(diǎn)。 middleware 最優(yōu)秀的特性就是可以被鏈?zhǔn)浇M合。你可以在一個(gè)項(xiàng)目中使用多個(gè)獨(dú)立的第三方 middleware。
注意 applyMiddleware 的實(shí)現(xiàn)方式。
// 警告:這只是一種“單純”的實(shí)現(xiàn)方式!
// 這 *并不是* Redux 的 API.
function applyMiddleware(store, middlewares) {
middlewares = middlewares.slice()
middlewares.reverse()
let dispatch = store.dispatch
middlewares.forEach(middleware =>
dispatch = middleware(store)(dispatch)
)
return Object.assign({}, store, { dispatch })
}
計(jì)算衍生數(shù)據(jù)
Reselect 庫(kù)可以創(chuàng)建可記憶的(Memoized)、可組合的 selector 函數(shù)。Reselect selectors 可以用來(lái)高效地計(jì)算 Redux store 里的衍生數(shù)據(jù)。
實(shí)現(xiàn)撤銷歷史
reducer enhance 的產(chǎn)生
combineReducer
- 在生成新的 state 樹(shù)時(shí),combinerReducers 將調(diào)用每一個(gè)拆分之后的 reducer 和與當(dāng)前的 Action,如果有需要的話會(huì)使得每一個(gè) reducer 有機(jī)會(huì)響應(yīng)和更新拆分后的 state。所以,在這個(gè)意義上, combineReducers 會(huì)調(diào)用所有的 reducer,嚴(yán)格來(lái)說(shuō)是它包裝的所有 reducer。
- 你可以在任何級(jí)別的 reducer 中使用 combineReducer,不僅僅是在創(chuàng)建根 reducer 的時(shí)候。
State 范式化(重要)
在 Redux Store 中管理關(guān)系數(shù)據(jù)或嵌套數(shù)據(jù)的推薦做法是將這一部分視為數(shù)據(jù)庫(kù),并且將數(shù)據(jù)按范式化存儲(chǔ)。因?yàn)椋?/strong>
- 當(dāng)數(shù)據(jù)在多處冗余后,需要更新時(shí),很難保證所有的數(shù)據(jù)都進(jìn)行更新。
- 嵌套的數(shù)據(jù)意味著 reducer 邏輯嵌套更多、復(fù)雜度更高。尤其是在打算更新深層嵌套數(shù)據(jù)時(shí)。
- 不可變的數(shù)據(jù)在更新時(shí)需要狀態(tài)樹(shù)的祖先數(shù)據(jù)進(jìn)行復(fù)制和更新,并且新的對(duì)象引用會(huì)導(dǎo)致與之 connect 的所有 UI 組件都重復(fù) render。盡管要顯示的數(shù)據(jù)沒(méi)有發(fā)生任何改變,對(duì)深層嵌套的數(shù)據(jù)對(duì)象進(jìn)行更新也會(huì)強(qiáng)制完全無(wú)關(guān)的 UI 組件重復(fù) render
如何設(shè)計(jì)范式數(shù)據(jù):
- 任何類型的數(shù)據(jù)在 state 中都有自己的 “表”。
- 任何 “數(shù)據(jù)表” 應(yīng)將各個(gè)項(xiàng)目存儲(chǔ)在對(duì)象中,其中每個(gè)項(xiàng)目的 ID 作為 key,項(xiàng)目本身作為 value。
- 任何對(duì)單個(gè)項(xiàng)目的引用都應(yīng)該根據(jù)存儲(chǔ)項(xiàng)目的 ID 來(lái)完成。
- ID 數(shù)組應(yīng)該用于排序。
Reducer 邏輯復(fù)用
高階 reducer 是一個(gè)接收 reducer 函數(shù)作為參數(shù),并返回新的 reducer 函數(shù)的函數(shù)。它也可以被看作成一個(gè)“reducer 工廠”。
創(chuàng)建特定的 reducer 有兩種最常見(jiàn)的方式,一個(gè)是使用給定的前綴或者后綴生成新的 action 常量,另一個(gè)是在 action 對(duì)象上附加額外的信息。下面是它們大概的樣子:
不可變更新模式
- 更新嵌套的對(duì)象
- 在數(shù)組中插入和刪除數(shù)據(jù)
- 在一個(gè)數(shù)組中更新一個(gè)項(xiàng)目
- 不可變更新工具庫(kù)
初始化 State
他們會(huì)優(yōu)先選擇通過(guò) preloadedState 參數(shù)傳到 createStore() 的對(duì)象中的相應(yīng)值,但是如果你不傳任何東西,或者沒(méi)設(shè)置相應(yīng)的字段,那么 reducer 就會(huì)選擇指定的默認(rèn) state 參數(shù)來(lái)取代。