From 78f116d4e91acfc2f15ce6a35ceea18007379b92 Mon Sep 17 00:00:00 2001 From: Terry Appleby Date: Sun, 3 Apr 2016 22:23:52 -0400 Subject: [PATCH] Proof of concept: fully create store before dispatching init action. --- src/createStore.js | 59 +++++++++++++++++++++++++++------------- test/createStore.spec.js | 16 +++++++++++ 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/createStore.js b/src/createStore.js index 68097d1ce3..b8f8193e0e 100644 --- a/src/createStore.js +++ b/src/createStore.js @@ -35,20 +35,7 @@ export var ActionTypes = { * @returns {Store} A Redux store that lets you read the state, dispatch actions * and subscribe to changes. */ -export default function createStore(reducer, initialState, enhancer) { - if (typeof initialState === 'function' && typeof enhancer === 'undefined') { - enhancer = initialState - initialState = undefined - } - - if (typeof enhancer !== 'undefined') { - if (typeof enhancer !== 'function') { - throw new Error('Expected the enhancer to be a function.') - } - - return enhancer(createStore)(reducer, initialState) - } - +export function createStore(reducer, initialState) { if (typeof reducer !== 'function') { throw new Error('Expected the reducer to be a function.') } @@ -198,11 +185,6 @@ export default function createStore(reducer, initialState, enhancer) { dispatch({ type: ActionTypes.INIT }) } - // When a store is created, an "INIT" action is dispatched so that every - // reducer returns their initial state. This effectively populates - // the initial state tree. - dispatch({ type: ActionTypes.INIT }) - return { dispatch, subscribe, @@ -210,3 +192,42 @@ export default function createStore(reducer, initialState, enhancer) { replaceReducer } } + +/** + * + * TODO: Docs. + * + * @param {Function} reducer @see createStore + * + * @param {any} [initialState] @see createStore + * + * @param {Function} enhancer The store enhancer. You may optionally specify it + * to enhance the store with third-party capabilities such as middleware, + * time travel, persistence, etc. The only store enhancer that ships with Redux + * is `applyMiddleware()`. + * + * @returns {Store} An initialized Redux store that lets you read the state, + * dispatch actions and subscribe to changes. + */ +export default function initializeStore(reducer, initialState, enhancer) { + if (typeof initialState === 'function' && typeof enhancer === 'undefined') { + enhancer = initialState + initialState = undefined + } + + if (typeof enhancer !== 'undefined') { + if (typeof enhancer !== 'function') { + throw new Error('Expected the enhancer to be a function.') + } + } + + var finalCreateStore = enhancer ? enhancer(createStore) : createStore + var store = finalCreateStore(reducer, initialState) + + // When a store is created, an "INIT" action is dispatched so that every + // reducer returns their initial state. This effectively populates + // the initial state tree. + store.dispatch({ type: ActionTypes.INIT }) + + return store +} diff --git a/test/createStore.spec.js b/test/createStore.spec.js index 3a8af0630b..dd14ca9cfe 100644 --- a/test/createStore.spec.js +++ b/test/createStore.spec.js @@ -1,5 +1,6 @@ import expect from 'expect' import { createStore, combineReducers } from '../src/index' +import { ActionTypes } from '../src/createStore' import { addTodo, dispatchInMiddle, throwError, unknownAction } from './helpers/actionCreators' import * as reducers from './helpers/reducers' @@ -610,4 +611,19 @@ describe('createStore', () => { store.subscribe(undefined) ).toThrow() }) + + it('fully initializes store before dispatching init action', () => { + const spyEnhancer = vanillaCreateStore => (...args) => { + const vanillaStore = vanillaCreateStore(...args) + return { + ...vanillaStore, + dispatch: expect.createSpy(vanillaStore.dispatch).andCallThrough() + } + } + + const store = createStore(reducers.todos, spyEnhancer) + + expect(store.dispatch).toHaveBeenCalledWith({ type: ActionTypes.INIT }) + }) + })