diff --git a/src/Redux.js b/src/Redux.js
index f60cc5aa52..010312f659 100644
--- a/src/Redux.js
+++ b/src/Redux.js
@@ -1,9 +1,10 @@
 import createDispatcher from './createDispatcher';
 import composeStores from './utils/composeStores';
 import thunkMiddleware from './middleware/thunk';
+import identity from 'lodash/utility/identity';
 
 export default class Redux {
-  constructor(dispatcher, initialState) {
+  constructor(dispatcher, initialState, prepareState = identity) {
     if (typeof dispatcher === 'object') {
       // A shortcut notation to use the default dispatcher
       dispatcher = createDispatcher(
@@ -13,6 +14,7 @@ export default class Redux {
     }
 
     this.state = initialState;
+    this.prepareState = prepareState;
     this.listeners = [];
     this.replaceDispatcher(dispatcher);
   }
@@ -23,17 +25,25 @@ export default class Redux {
 
   replaceDispatcher(nextDispatcher) {
     this.dispatcher = nextDispatcher;
-    this.dispatchFn = nextDispatcher(this.state, ::this.setState);
+    this.dispatchFn = nextDispatcher({
+      getState: ::this.getRawState,
+      setState: ::this.setState
+    });
+    this.dispatch({});
   }
 
   dispatch(action) {
     return this.dispatchFn(action);
   }
 
-  getState() {
+  getRawState() {
     return this.state;
   }
 
+  getState() {
+    return this.prepareState(this.state);
+  }
+
   setState(nextState) {
     this.state = nextState;
     this.listeners.forEach(listener => listener());
diff --git a/src/createDispatcher.js b/src/createDispatcher.js
index 5b1b36bac9..50689d27c5 100644
--- a/src/createDispatcher.js
+++ b/src/createDispatcher.js
@@ -1,20 +1,14 @@
 import composeMiddleware from './utils/composeMiddleware';
 
 export default function createDispatcher(store, middlewares = []) {
-  return function dispatcher(initialState, setState) {
-    let state = setState(store(initialState, {}));
-
+  return function dispatcher({ getState, setState }) {
     function dispatch(action) {
-      state = setState(store(state, action));
+      setState(store(getState(), action));
       return action;
     }
 
-    function getState() {
-      return state;
-    }
-
     const finalMiddlewares = typeof middlewares === 'function' ?
-      middlewares(getState) :
+      middlewares(getState, setState, dispatch) :
       middlewares;
 
     return composeMiddleware(...finalMiddlewares, dispatch);
diff --git a/test/components/Connector.spec.js b/test/components/Connector.spec.js
index 04998f9741..79709078ab 100644
--- a/test/components/Connector.spec.js
+++ b/test/components/Connector.spec.js
@@ -188,13 +188,13 @@ describe('React', () => {
     });
 
     it('should throw an error if `state` returns anything but a plain object', () => {
-      const redux = createRedux(() => {});
+      const redux = createRedux({ test: () => 'test' });
 
       expect(() => {
         TestUtils.renderIntoDocument(
           <Provider redux={redux}>
             {() => (
-              <Connector state={() => 1}>
+              <Connector select={() => 1}>
                 {() => <div />}
               </Connector>
             )}
diff --git a/test/createDispatcher.spec.js b/test/createDispatcher.spec.js
index 40991bfcec..74911e6604 100644
--- a/test/createDispatcher.spec.js
+++ b/test/createDispatcher.spec.js
@@ -8,34 +8,33 @@ const { addTodo, addTodoAsync } = todoActions;
 const { ADD_TODO } = constants;
 
 describe('createDispatcher', () => {
-
   it('should handle sync and async dispatches', done => {
-    const spy = expect.createSpy(
-      nextState => nextState
-    ).andCallThrough();
-
     const dispatcher = createDispatcher(
       composeStores({ todoStore }),
       // we need this middleware to handle async actions
-      getState => [thunkMiddleware(getState)]
+      ({ _getState, _dispatch }) => [thunkMiddleware(_getState, _dispatch)]
     );
 
     expect(dispatcher).toBeA('function');
 
-    const dispatchFn = dispatcher(undefined, spy);
-    expect(spy.calls.length).toBe(1);
-    expect(spy).toHaveBeenCalledWith({ todoStore: [] });
+    // Mock Redux interface
+    let state, dispatchFn;
+    const getState = () => state;
+    const dispatch = action => dispatchFn(action);
+    const setState = newState => state = newState;
+
+    dispatchFn = dispatcher({ getState, setState, dispatch });
+    dispatchFn({}); // Initial dispatch
+    expect(state).toEqual({ todoStore: [] });
 
     const addTodoAction = dispatchFn(addTodo(defaultText));
     expect(addTodoAction).toEqual({ type: ADD_TODO, text: defaultText });
-    expect(spy.calls.length).toBe(2);
-    expect(spy).toHaveBeenCalledWith({ todoStore: [
+    expect(state).toEqual({ todoStore: [
       { id: 1, text: defaultText }
     ] });
 
     dispatchFn(addTodoAsync(('Say hi!'), () => {
-      expect(spy.calls.length).toBe(3);
-      expect(spy).toHaveBeenCalledWith({ todoStore: [
+      expect(state).toEqual({ todoStore: [
         { id: 2, text: 'Say hi!' },
         { id: 1, text: defaultText }
       ] });
diff --git a/test/createRedux.spec.js b/test/createRedux.spec.js
index 1900de351c..f2dc80d299 100644
--- a/test/createRedux.spec.js
+++ b/test/createRedux.spec.js
@@ -69,4 +69,29 @@ describe('createRedux', () => {
 
     expect(state).toEqual(redux.getState().todoStore);
   });
+
+  it('should handle nested dispatches gracefully', () => {
+    function foo(state = 0, action) {
+      return action.type === 'foo' ? 1 : state;
+    }
+
+    function bar(state = 0, action) {
+      return action.type === 'bar' ? 2 : state;
+    }
+
+    redux = createRedux({ foo, bar });
+
+    redux.subscribe(() => {
+      // What the Connector ends up doing.
+      const state = redux.getState();
+      if (state.bar === 0) {
+        redux.dispatch({type: 'bar'});
+      }
+    });
+
+    redux.dispatch({type: 'foo'});
+
+    // Either this or throw an error when nesting dispatchers
+    expect(redux.getState()).toEqual({foo: 1, bar: 2});
+  });
 });