Redux 是 JavaScript 狀態容器,提供可預測化的狀態管理。前端
它認爲:Web應用是一個狀態機,視圖與狀態一一對應。從架構層面來講,一般但願UI跟數據、邏輯分離,直觀體現就是:UI = render(state)服務器
如今的Web應用涉及大量數據交互、異步操做等,無疑都在增長前端的複雜性,須要維護的state也愈來愈多。而Redux就是試圖讓每一個state變化都是可預測,將應用中全部的action與state統一管理。markdown
在講Redux的工做流程以前,需瞭解幾個Redux相關的核心概念:架構
具體工做流程: 用戶經過View(或服務器響應)觸發Action,Dispatch方法將Action Creator函數生成的Action派發到Store,Store自動調用Reducer,並向它傳入當前State和Action,Reducer返回新的State,State一旦有變化,Store就會經過監聽函數來更新View。 借用一張圖來描述這一過程: app
嚴格的單向數據流是 Redux 架構的設計核心。異步
以從服務器響應文章內容爲例 Action函數
const LOAD_ARTICLES_DETAIL = 'LOAD_ARTICLES_DETAIL' const LOAD_ARTICLES_DETAIL_SUCCESS = 'LOAD_ARTICLES_DETAIL_SUCCESS' const LOAD_ARTICLES_DETAIL_ERROR = 'LOAD_ARTICLES_DETAIL_ERROR' 複製代碼
Action Creatorspa
export const loadArticlesDetail = () => ({ type: LOAD_ARTICLES_DETAIL }) export const loadArticlesDetailSuccess = result => ({ type: LOAD_ARTICLES_DETAIL_SUCCESS, result }) export const loadArticlesDetailFailure = error => ({ type: LOAD_ARTICLES_DETAIL_ERROR, error }) 複製代碼
Store設計
const store = createStore(reducers) 複製代碼
Reducer (previousState, action) => (newState)code
export default (state = initalState, action) => { switch (action.type) { case LOAD_ARTICLES_DETAIL: { return { ...state, loading: true, error: false } } case LOAD_ARTICLES_DETAIL_SUCCESS: { return { ...state, loading: false, error: false, articlesDetail: action.result } } case LOAD_ARTICLES_DETAIL_ERROR: { return { ...state, loading: false, error: true } } default: return state } } 複製代碼
Redux主要源碼總體結構:
export { createStore, combineReducers, bindActionCreators, applyMiddleware, compose } 複製代碼
這是入口文件導出的方法,也是Redux支持的方法,這些方法的實如今主工做流程文件和輔助函數文件,接下來看主工做流程。
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { const store = createStore(reducer, preloadedState, enhancer) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } } 複製代碼
從源碼上看,最後是返回了一個Store和一個被更新過的dispatch方法,實現了對Store的加強。
export default function bindActionCreators(actionCreators, dispatch) { if (typeof actionCreators === 'function') { return bindActionCreator(actionCreators, dispatch) } } 複製代碼
使用dispatch把action creator都包裝起來,這樣能夠直接調用它們。
export default function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) } 複製代碼compose這個方法,傳入的一系列函數,執行的最終結果是把各個函數串聯起來。