Redux介绍之Store

13 May

前几篇介绍了Action和Reducer,它们的目的是为了更新Store里的state。我将Store理解为一个数据库DB,它不是数据,真正的数据是state。Store提供了方法能让用户操作存储在里面的数据state。本篇介绍一下Store,源码已上传Github,请参照src/originReduxStore文件夹。

  • Store的诞生(createStore)
  • Store的方法(getState,dispatch,subscribe)

Store的诞生(createStore)

Redux提供了createStore(reducer, [initialState], [enhancer])方法来创建Store。

第一个参数reducer,在Redux介绍之Reducer中介绍过,不赘述。

第二个可选参数initialState用于初始化state。

第三个可选参数enhancer是一个高价函数,通过compose(…functions)方法,从参数右向左依次合并返回一个高价函数,最终得到一个增强版的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了浏览器调试工具Redux DevTools和中间件logger。中间件的概念以后会介绍,现在你可以理解为:前几篇生成的是普通Store,而本篇生成的是Store中的战斗机,可适配浏览器调试工具,且每次Reducer更新state时都会打印出log。插件和logger中间件的效果如下图:

redux

Store的方法(getState,dispatch,subscribe)

生成的Store提供了3个方法:getState(),dispatch(action),subscribe(listener)

getState():获取Store里存储的state,比较简单,不赘述。

dispatch(action):分派Action,Action的概念见Redux介绍之Action,不赘述。

subscribe(listener):注册回调函数,当state发生变化后会触发注册的回调函数。该方法的返回值也是一个函数对象,调用后可以取消注册的回调函数,参照entries/originReduxStore.js:

const cancelUpdate = store.subscribe(update);

页面上增加一个unsubscribe按钮,按钮的onClick方法里调用上述cancelUpdate,点击该按钮后,以后再更新state,将不会触发update,页面将不再刷新:

redux

那Store是如何实现提供上述3个方法的呢?参见React.js小书里,我们自己来实现个简易版createStore。参照lib/common.js:

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,
    };
};

代码都是自解释代码,应该不难看懂。用这个我们自己写的简易版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按钮,其他运行正常,效果令人满意。最后总结一下Store:它是一个由createStore创建,能提供getState,dispatch,subscribe方法,内部存储数据state的仓库。

Leave a Reply

Your email address will not be published. Required fields are marked *