前幾篇介紹了Action和Reducer,它們的目的是為了更新Store里的state。我將Store理解為一個數(shù)據(jù)庫DB,它不是數(shù)據(jù)躏鱼,真正的數(shù)據(jù)是state。Store提供了方法能讓用戶操作存儲在里面的數(shù)據(jù)state殷绍。本篇介紹一下Store,源碼已上傳Github鹊漠,請參照src/originReduxStore文件夾主到。
- Store的誕生(createStore)
- Store的方法(getState,dispatch躯概,subscribe)
Store的誕生(createStore)
Redux提供了createStore(reducer, [initialState], [enhancer])方法來創(chuàng)建Store登钥。
第一個參數(shù)reducer,在Redux介紹之Reducer中介紹過娶靡,不贅述牧牢。
第二個可選參數(shù)initialState用于初始化state。
第三個可選參數(shù)enhancer是一個高價函數(shù)姿锭,通過compose(…functions)方法塔鳍,從參數(shù)右向左依次合并返回一個高價函數(shù),最終得到一個增強(qiáng)版的createStore方法呻此,例如entries/originReduxStore.js:
import { createStore, applyMiddleware, compose } from 'redux';
import { createLogger } from 'redux-logger';
const logger = createLogger();
const store = createStore(reducer, compose(
applyMiddleware(logger),
window.devToolsExtension ? window.devToolsExtension() : (f) => f,
));
上述代碼中轮纫,compose了瀏覽器調(diào)試工具Redux DevTools和中間件logger。中間件的概念以后會介紹焚鲜,現(xiàn)在你可以理解為:前幾篇生成的是普通Store掌唾,而本篇生成的是Store中的戰(zhàn)斗機(jī)放前,可適配瀏覽器調(diào)試工具,且每次Reducer更新state時都會打印出log糯彬。插件和logger中間件的效果如下圖:
Store的方法(getState凭语,dispatch,subscribe)
生成的Store提供了3個方法:getState()撩扒,dispatch(action)似扔,subscribe(listener)
getState():獲取Store里存儲的state,比較簡單却舀,不贅述虫几。
dispatch(action):分派Action,Action的概念見Redux介紹之Action挽拔,不贅述辆脸。
subscribe(listener):注冊回調(diào)函數(shù),當(dāng)state發(fā)生變化后會觸發(fā)注冊的回調(diào)函數(shù)螃诅。該方法的返回值也是一個函數(shù)對象啡氢,調(diào)用后可以取消注冊的回調(diào)函數(shù),參照entries/originReduxStore.js:
const cancelUpdate = store.subscribe(update);
頁面上增加一個unsubscribe按鈕术裸,按鈕的onClick方法里調(diào)用上述cancelUpdate倘是,點(diǎn)擊該按鈕后,以后再更新state袭艺,將不會觸發(fā)update搀崭,頁面將不再刷新:
export const createStore = (reducer) => {
let state = {};
const listeners = [];
const getState = () => state;
const dispatch = (action) => {
state = reducer(state, action);
listeners.forEach((listener) => listener());
};
const subscribe = (listener) => listeners.push(listener);
return {
getState,
dispatch,
subscribe,
};
};
代碼都是自解釋代碼,應(yīng)該不難看懂答倡。用這個我們自己寫的簡易版createStore替換Redux提供的createStore試試:
// import { createStore, applyMiddleware, compose } from 'redux';
import { applyMiddleware, compose } from 'redux';
import { createStore } from '../lib/common';
// const logger = createLogger();
// const store = createStore(reducer, compose(
// applyMiddleware(logger),
// window.devToolsExtension ? window.devToolsExtension() : (f) => f,
// ));
const store = createStore(reducer);
效果一樣轰传,頁面上除了unsubscribe按鈕,其他運(yùn)行正常瘪撇,效果令人滿意获茬。最后總結(jié)一下Store:它是一個由createStore創(chuàng)建,能提供getState倔既,dispatch恕曲,subscribe方法,內(nèi)部存儲數(shù)據(jù)state的倉庫渤涌。