diff --git a/packages/react-dev-utils/webpackHotDevClient.js b/packages/react-dev-utils/webpackHotDevClient.js
index 18a6a4a0ae172dacfa6ea1a8edfefd8265998aaf..b0508dc4d231933db9602608128ca8a91f50991e 100644
--- a/packages/react-dev-utils/webpackHotDevClient.js
+++ b/packages/react-dev-utils/webpackHotDevClient.js
@@ -25,13 +25,17 @@ var launchEditorEndpoint = require('./launchEditorEndpoint');
 var formatWebpackMessages = require('./formatWebpackMessages');
 var ErrorOverlay = require('react-error-overlay');
 
+// We need to keep track of if there has been a runtime error.
+// Essentially, we cannot guarantee application state was not corrupted by the
+// runtime error. To prevent confusing behavior, we forcibly reload the entire
+// application. This is handled below when we are notified of a compile (code
+// change).
+// See https://github.com/facebookincubator/create-react-app/issues/3096
+var hadRuntimeError = false;
 ErrorOverlay.startReportingRuntimeErrors({
   launchEditorEndpoint: launchEditorEndpoint,
   onError: function() {
-    // TODO: why do we need this?
-    if (module.hot && typeof module.hot.decline === 'function') {
-      module.hot.decline();
-    }
+    hadRuntimeError = true;
   },
   filename: '/static/js/bundle.js',
 });
@@ -227,7 +231,7 @@ function tryApplyUpdates(onHotUpdateSuccess) {
   }
 
   function handleApplyUpdates(err, updatedModules) {
-    if (err || !updatedModules) {
+    if (err || !updatedModules || hadRuntimeError) {
       window.location.reload();
       return;
     }