diff --git a/src/createStore.js b/src/createStore.js
index 68097d1ce3..238157b4d8 100644
--- a/src/createStore.js
+++ b/src/createStore.js
@@ -71,6 +71,14 @@ export default function createStore(reducer, initialState, enhancer) {
    * @returns {any} The current state tree of your application.
    */
   function getState() {
+    if (isDispatching) {
+      throw new Error(
+        'You may not call store.getState() while the reducer is executing. ' +
+        'The reducer has already received the state as an argument. ' +
+        'Pass it down from the top reducer instead of reading it from the store.'
+      )
+    }
+
     return currentState
   }
 
@@ -102,6 +110,15 @@ export default function createStore(reducer, initialState, enhancer) {
       throw new Error('Expected listener to be a function.')
     }
 
+    if (isDispatching) {
+      throw new Error(
+        'You may not call store.subscribe() while the reducer is executing. ' +
+        'If you would like to be notified after the store has been updated, subscribe from a ' +
+        'component and invoke store.getState() in the callback to access the latest state. ' +
+        'See http://redux.js.org/docs/api/Store.html#subscribe for more details.'
+      )
+    }
+
     var isSubscribed = true
 
     ensureCanMutateNextListeners()
@@ -112,6 +129,13 @@ export default function createStore(reducer, initialState, enhancer) {
         return
       }
 
+      if (isDispatching) {
+        throw new Error(
+          'You may not unsubscribe from a store listener while the reducer is executing. ' +
+          'See http://redux.js.org/docs/api/Store.html#subscribe for more details.'
+        )
+      }
+
       isSubscribed = false
 
       ensureCanMutateNextListeners()
diff --git a/test/createStore.spec.js b/test/createStore.spec.js
index 3a8af0630b..b2b6105bf2 100644
--- a/test/createStore.spec.js
+++ b/test/createStore.spec.js
@@ -1,6 +1,14 @@
 import expect from 'expect'
 import { createStore, combineReducers } from '../src/index'
-import { addTodo, dispatchInMiddle, throwError, unknownAction } from './helpers/actionCreators'
+import { 
+  addTodo, 
+  dispatchInMiddle, 
+  getStateInMiddle,
+  subscribeInMiddle,
+  unsubscribeInMiddle,
+  throwError, 
+  unknownAction 
+} from './helpers/actionCreators'
 import * as reducers from './helpers/reducers'
 
 describe('createStore', () => {
@@ -451,6 +459,31 @@ describe('createStore', () => {
     ).toThrow(/may not dispatch/)
   })
 
+  it('does not allow getState() from within a reducer', () => {
+    const store = createStore(reducers.getStateInTheMiddleOfReducer)
+
+    expect(() =>
+      store.dispatch(getStateInMiddle(store.getState.bind(store)))
+    ).toThrow(/You may not call store.getState()/)
+  })
+
+  it('does not allow subscribe() from within a reducer', () => {
+    const store = createStore(reducers.subscribeInTheMiddleOfReducer)
+
+    expect(() =>
+      store.dispatch(subscribeInMiddle(store.subscribe.bind(store, () => {})))
+    ).toThrow(/You may not call store.subscribe()/)
+  })
+
+  it('does not allow unsubscribe from subscribe() from within a reducer', () => {
+    const store = createStore(reducers.unsubscribeInTheMiddleOfReducer)
+    const unsubscribe = store.subscribe(() => {})
+
+    expect(() =>
+      store.dispatch(unsubscribeInMiddle(unsubscribe.bind(store)))
+    ).toThrow(/You may not unsubscribe from a store/)
+  })
+
   it('recovers from an error within a reducer', () => {
     const store = createStore(reducers.errorThrowingReducer)
     expect(() =>
diff --git a/test/helpers/actionCreators.js b/test/helpers/actionCreators.js
index 198f61be20..5c26cdcc41 100644
--- a/test/helpers/actionCreators.js
+++ b/test/helpers/actionCreators.js
@@ -1,4 +1,12 @@
-import { ADD_TODO, DISPATCH_IN_MIDDLE, THROW_ERROR, UNKNOWN_ACTION } from './actionTypes'
+import { 
+  ADD_TODO, 
+  DISPATCH_IN_MIDDLE, 
+  GET_STATE_IN_MIDDLE, 
+  SUBSCRIBE_IN_MIDDLE,
+  UNSUBSCRIBE_IN_MIDDLE, 
+  THROW_ERROR, 
+  UNKNOWN_ACTION 
+} from './actionTypes'
 
 export function addTodo(text) {
   return { type: ADD_TODO, text }
@@ -26,6 +34,27 @@ export function dispatchInMiddle(boundDispatchFn) {
   }
 }
 
+export function getStateInMiddle(boundGetStateFn) {
+  return {
+    type: GET_STATE_IN_MIDDLE,
+    boundGetStateFn
+  }
+}
+
+export function subscribeInMiddle(boundSubscribeFn) {
+  return {
+    type: SUBSCRIBE_IN_MIDDLE,
+    boundSubscribeFn
+  }
+}
+
+export function unsubscribeInMiddle(boundUnsubscribeFn) {
+  return {
+    type: UNSUBSCRIBE_IN_MIDDLE,
+    boundUnsubscribeFn
+  }
+}
+
 export function throwError() {
   return {
     type: THROW_ERROR
diff --git a/test/helpers/actionTypes.js b/test/helpers/actionTypes.js
index 00092962f2..2e6104345c 100644
--- a/test/helpers/actionTypes.js
+++ b/test/helpers/actionTypes.js
@@ -1,4 +1,7 @@
 export const ADD_TODO = 'ADD_TODO'
 export const DISPATCH_IN_MIDDLE = 'DISPATCH_IN_MIDDLE'
+export const GET_STATE_IN_MIDDLE = 'GET_STATE_IN_MIDDLE'
+export const SUBSCRIBE_IN_MIDDLE = 'SUBSCRIBE_IN_MIDDLE'
+export const UNSUBSCRIBE_IN_MIDDLE = 'UNSUBSCRIBE_IN_MIDDLE'
 export const THROW_ERROR = 'THROW_ERROR'
 export const UNKNOWN_ACTION = 'UNKNOWN_ACTION'
diff --git a/test/helpers/reducers.js b/test/helpers/reducers.js
index 8e9c7321ec..31ce7b99e1 100644
--- a/test/helpers/reducers.js
+++ b/test/helpers/reducers.js
@@ -1,4 +1,11 @@
-import { ADD_TODO, DISPATCH_IN_MIDDLE, THROW_ERROR } from './actionTypes'
+import { 
+  ADD_TODO, 
+  DISPATCH_IN_MIDDLE, 
+  GET_STATE_IN_MIDDLE, 
+  SUBSCRIBE_IN_MIDDLE,
+  UNSUBSCRIBE_IN_MIDDLE,
+  THROW_ERROR 
+} from './actionTypes'
 
 
 function id(state = []) {
@@ -46,6 +53,36 @@ export function dispatchInTheMiddleOfReducer(state = [], action) {
   }
 }
 
+export function getStateInTheMiddleOfReducer(state = [], action) {
+  switch (action.type) {
+    case GET_STATE_IN_MIDDLE:
+      action.boundGetStateFn()
+      return state
+    default:
+      return state
+  }
+}
+
+export function subscribeInTheMiddleOfReducer(state = [], action) {
+  switch (action.type) {
+    case SUBSCRIBE_IN_MIDDLE:
+      action.boundSubscribeFn()
+      return state
+    default:
+      return state
+  }
+}
+
+export function unsubscribeInTheMiddleOfReducer(state = [], action) {
+  switch (action.type) {
+    case UNSUBSCRIBE_IN_MIDDLE:
+      action.boundUnsubscribeFn()
+      return state
+    default:
+      return state
+  }
+}
+
 export function errorThrowingReducer(state = [], action) {
   switch (action.type) {
     case THROW_ERROR: