動機
- JavaScript 需要管理比任何時候都要多的 state (狀態(tài))
- state 在什么時候,由于什么原因,如何變化已然不受控制
- 我們總是將兩個難以理清的概念混淆在一起:變化和異步
通過限制更新發(fā)生的時間和方式,Redux 試圖讓 state 的變化變得可預(yù)測。這些限制條件反映在 Redux 的三大原則中。
核心概念
使用普通對象來描述應(yīng)用的 state ,強制使用 action 來描述所有變化,為了把 action 和 state 串起來,開發(fā)一些函數(shù),這就是 reducer。
三大原則
- 單一數(shù)據(jù)源
- State 是只讀的
- 使用純函數(shù)來執(zhí)行修改(reducer)
生態(tài)系統(tǒng)
與框架的綁定、中間件、增強器等
Action
- Action 本質(zhì)上是 JavaScript 普通對象。我們約定,action 內(nèi)必須使用一個字符串類型的 type 字段來表示將要執(zhí)行的動作。
- Action 創(chuàng)建函數(shù) 就是生成 action 的方法
Reducer
- state 結(jié)構(gòu)的設(shè)計
開發(fā)復(fù)雜的應(yīng)用時,不可避免會有一些數(shù)據(jù)相互引用。建議你盡可能地把 state 范式化,不存在嵌套。把所有數(shù)據(jù)放到一個對象里,每個數(shù)據(jù)以 ID 為主鍵,不同實體或列表間通過 ID 相互引用數(shù)據(jù)。把應(yīng)用的 state 想像成數(shù)據(jù)庫。這種方法在 normalizr 文檔里有詳細(xì)闡述。例如,實際開發(fā)中,在 state 里同時存放todosById: { id -> todo }和todos: array<id>是比較好的方式, - 保持 reducer 純凈非常重要
只要傳入?yún)?shù)相同,返回計算得到的下一個 state 就一定相同。沒有特殊情況、沒有副作用,沒有 API 請求、沒有變量修改,單純執(zhí)行計算。 - 拆分 Reducer
每個 reducer 只負(fù)責(zé)管理全局 state 中它負(fù)責(zé)的一部分。每個 reducer 的 state 參數(shù)都不同,分別對應(yīng)它管理的那部分 state 數(shù)據(jù)
Store
getState() dispatch(action) subscribe(listener)
數(shù)據(jù)流
嚴(yán)格的單向數(shù)據(jù)流是 Redux 架構(gòu)的設(shè)計核心。
- 調(diào)用
store.dispatch(action)。 - Redux store 調(diào)用傳入的 reducer 函數(shù)。
- 根 reducer 應(yīng)該把多個子 reducer 輸出合并成一個單一的 state 樹。
- Redux store 保存了根 reducer 返回的完整 state 樹。
搭配 React
Redux 的 React 綁定庫是基于 容器組件和展示組件相分離 的開發(fā)思想。