本文主要是對 Redux 官方文檔 的梳理以及自身對 Redux 的理解。html
對於複雜的單頁面應用,狀態(state)管理很是重要。state 可能包括:服務端的響應數據、本地對響應數據的緩存、本地建立的數據(好比,表單數據)以及一些 UI 的狀態信息(好比,路由、選中的 tab、是否顯示下拉列表、頁碼控制等等)。若是 state 變化不可預測,就會難於調試(state 不易重現,很難復現一些 bug)和不易於擴展(好比,優化更新渲染、服務端渲染、路由切換時獲取數據等等)。react
Redux 就是用來確保 state 變化的可預測性,主要的約束有:git
state 以單一對象存儲在 store 對象中github
state 只讀ajax
使用純函數 reducer 執行 state 更新redux
state 爲單一對象,使得 Redux 只須要維護一棵狀態樹,服務端很容易初始化狀態,易於服務器渲染。state 只能經過 dispatch(action) 來觸發更新,更新邏輯由 reducer 來執行。promise
action 能夠理解爲應用向 store 傳遞的數據信息(通常爲用戶交互信息)。在實際應用中,傳遞的信息能夠約定一個固定的數據格式,好比: Flux Standard Action。
爲了便於測試和易於擴展,Redux 引入了 Action Creator:緩存
function addTodo(text) { return { type: ADD_TODO, text, } } store.dispatch(addTodo(text))
dispatch(action) 是一個同步的過程:執行 reducer 更新 state -> 調用 store 的監聽處理函數。若是須要在 dispatch 時執行一些異步操做(fetch action data),能夠經過引入 Middleware 解決。服務器
reducer 實際上就是一個函數:(previousState, action) => newState
。用來執行根據指定 action 來更新 state 的邏輯。經過 combineReducers(reducers) 能夠把多個 reducer 合併成一個 root reducer。架構
reducer 不存儲 state, reducer 函數邏輯中不該該直接改變 state 對象, 而是返回新的 state 對象(能夠考慮使用 immutable-js)。
store 是一個單一對象:
管理應用的 state
經過 store.getState()
能夠獲取 state
經過 store.dispatch(action)
來觸發 state 更新
經過 store.subscribe(listener)
來註冊 state 變化監聽器
經過 createStore(reducer, [initialState])
建立
在 Redux 應用中,只容許有一個 store 對象,能夠經過 combineReducers(reducers) 來實現對 state 管理的邏輯劃分(多個 reducer)。
middleware 其實就是高階函數,做用於 dispatch 返回一個新的 dispatch(附加了該中間件功能)。能夠形式化爲:newDispatch = middleware1(middleware2(...(dispatch)...))
。
// thunk-middleware export default function thunkMiddleware({ dispatch, getState }) { return next => action => typeof action === 'function' ? action(dispatch, getState) : next(action) }
經過 thunk-middleware 咱們能夠看出中間件的通常形式:中間件函數接受兩個參數參數: dispatch 和 getState(也就是說中間件能夠獲取 state 以及 dispatch new action
)。中間件通常返回 next(action)
(thunk-middleware 比較特殊,它用於 dispatch 執行異步回調的 action)。store 的建立過程以下:
const reducer = combineReducers(reducers) const finalCreateStore = applyMiddleware(promiseMiddleware, warningMiddleware, loggerMiddleWare)(createStore) const store = finalCreateStore(reducer)
單頁面應用中充斥着大量的異步請求(ajax)。dispatch(action) 是同步的,若是要處理異步 action,須要使用一些中間件。
redux-thunks 和 redux-promise 分別是使用異步回調和 Promise 來解決異步 action 問題的。
圖來自 UNIDIRECTIONAL USER INTERFACE ARCHITECTURES
Redux 和 React 是沒有必然關係的,Redux 用於管理 state,與具體的 View 框架無關。不過,Redux 特別適合那些 state => UI
的框架(好比:React, Deku)。
能夠使用 react-redux 來綁定 React,react-redux
綁定的組件咱們通常稱之爲 smart components
,Smart and Dumb Components 在 react-redux
中區分以下:
Location | Use React-Redux | To read data, they | To change data, they | |
---|---|---|---|---|
「Smart」 Components | Top level, route handlers | Yes | Subscribe to Redux state | Dispatch Redux actions |
「Dumb」 Components | Middle and leaf components | No | Read data from props | Invoke callbacks from props |
簡單來看:Smart component` 是鏈接 Redux 的組件(@connect),通常不可複用。Dumb component 是純粹的組件,通常可複用。二者的共同點是:無狀態,或者說狀態提取到上層,統一由 redux 的 store 來管理。redux state -> Smart component -> Dumb component -> Dumb component(經過 props 傳遞)。在實踐中,少許 Dumb component 容許自帶 UI 狀態信息(組件 unmount 後,不須要保留 UI 狀態)。值得注意的是,Smart component 是應用更新狀態的最小單元。實踐中,能夠將 route handlers 做爲 Smart component,一個 Smart component 對應一個 reducer。