/* * createStore 狀態容器 * @param reducers 容器總得須要知道是作什麼樣的改變 * @param initialState 初始化(預置)的 state */ const createStore = (reducers, initialState) => { // 經過 reducer 取到改變後的值,從新存儲 let currentReducer = reducers; // 存 let currentState = initialState; // 取 const getState = () => { return currentState; }; // 改 const dispatch = action => { currentState = currentReducer(currentState, action); return action; }; // 這裏可能還須要可被觀察的,留坑、不實現,有興趣的看文章後的源碼閱讀連接 return { getState, dispatch }; };
/* * action * @property type 描述須要作什麼操做 * @property preload 預加載數據,包含 state 的新值 */ const RESET = "RESET"; const RESET_ACTION = { type: RESET, preload: { count: 0 } };
/* * reducer * @currentState 當前的 state,舊值 * @action 該作什麼修改的類型描述 */ const reducer = (state = { count: 0 }, action) => { switch (action.type) { case RESET: { return { ...state, ...action.preload }; } default: { return state; } } };
const store = createStore(reducer); store.dispatch({ type: RESET, preload: { count: 10 } }); store.getState(); // output { count: 10} store.dispatch(RESET_ACTION); store.getState(); // output { count: 0}
dispatch({ type: "@redux/INIT" });
Middleware is the suggested way to extend Redux with custom functionality. Middleware lets you wrap the store's dispatch method for fun and profit. The key feature of middleware is that it is composable. Multiple middleware can be combined together, where each middleware requires no knowledge of what comes before or after it in the chain.
Middleware 是經過自定義功能來擴展 redux 的推薦方法,它可以讓你有效的包裹 store 的 dispatch 方法已達到所需的目的,其關鍵特徵在於組合,多個 middleware 可以進行組合,每一個 middleware 都是獨立的,它們不須要知道在流程的以前或以後會發生什麼。
var a = function(next) { console.log("a-before"); next(); console.log("a-after"); }; var dispatch = function(action) { console.log("do ", action); return action; }; a(dispatch); // output: // a-before // do undefined // a-after
var a = function(next) { return function(action) { console.log("a-before"); next(action); console.log("a-after"); }; }; var dispatch = function(action) { console.log("do ", action); return action; }; a(dispatch)("test action"); // output: // a-before // do test action // a-after
var a = function(next) { return function(action) { console.log("a-before"); next(action); console.log("a-after"); }; }; var b = function(next) { return function(action) { console.log("b-before"); next(action); console.log("b-after"); }; }; var dispatch = function(action) { console.log("do ", action); return action; }; a(b(dispatch))("test action"); // output: // a-before // b-before // do test action // b-after // a-after
var a = function(next) { return function(action) { console.log("a-before"); next(action); console.log("a-after"); }; }; var b = function(next) { return function(action) { console.log("b-before"); next(action); console.log("c-after"); }; }; var c = function(next) { return function(action) { console.log("c-before"); next(action); console.log("c-after"); }; }; var dispatch = function(action) { console.log("do ", action); return action; }; var d = [a, b, c].reduce((pre, now) => (...args) => pre(now(...args))); d(dispatch)("test action"); // output: // a-before // b-before // c-before // do test action // c-after // b-after // a-after
const 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))); };
/* * createStore 狀態容器 * @param reducers 容器總得須要知道是作什麼樣的改變 * @param initialState 初始化(預置)的 state * @param enhancer 擴展的 middlewares */ const createStore = (reducers, initialState, enhancer) => { // 參數互換 若是 initialState 是個函數,enhancer = undefined 則 enhancer 和 initialState 互換 if (typeof initialState === "function" && typeof enhancer === "undefined") { enhancer = initialState; initialState = undefined; } // 若是有 middleware 的時候,則 createStore 稍後處理,處理詳情參照 applyMiddleware 函數 if (typeof enhancer !== "undefined" && typeof enhancer === "function") { // 爲何是這樣寫? 繼續往下看 return enhancer(createStore)(reducer, initialState); } // ... // 以前的代碼 };
/* * applyMiddleware 實現中間件的應用 * @param ...middlewares 插入的 state 處理流程的中間件 */ const applyMiddleware = (...middlewares) => { // 傳入 middlewares return createStore => (...args) => { const store = createStore(...args); // middleware 內部能作的 state 操做 const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) }; // 將 middleware 處理,以 middlewareAPI 做爲參數執行而且取到 middleware 的內部函數 const chain = middlewares.map(middleware => middleware(middlewareAPI)); // 進行 compose 組合 // 如存在 3 個 middleware A(ABefore,AAfter) B(BBefore,BAfter) C(CBefore,CAfter) // 則執行順序是 ABefore - BBefore - CBefore - (真實的操做) - CAfter - BAfter - AAfter dispatch = compose(...chain)(store.dispatch); return { ...store, dispatch }; }; };
const logger = ({ getState }) => { return next => action => { console.log("will dispatch", action); const returnValue = next(action); console.log("state after dispatch", getState()); return returnValue; }; }; const store = createStore(reducer, applyMiddleware(logger)); store.dispatch(RESET_ACTION); // output // will dispatch {type: "RESET", preload: {…}} // do dispatch // state after dispatch {count: 0}