From e801daf147f5c81dfe7fa68a1dba292302ab1685 Mon Sep 17 00:00:00 2001 From: Anton Korzunov Date: Wed, 11 Sep 2019 10:43:08 +1000 Subject: [PATCH] fix: run hot in batched mode, fixes #1332 --- src/hot.dev.js | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/hot.dev.js b/src/hot.dev.js index c163eac9a..63d30dae6 100644 --- a/src/hot.dev.js +++ b/src/hot.dev.js @@ -1,4 +1,5 @@ import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; import hoistNonReactStatic from 'hoist-non-react-statics'; import { getComponentDisplayName } from './internal/reactUtils'; import AppContainer from './AppContainer.dev'; @@ -6,6 +7,7 @@ import reactHotLoader from './reactHotLoader'; import { isOpened as isModuleOpened, hotModule, getLastModuleOpened } from './global/modules'; import logger from './logger'; import { clearExceptions, logException } from './errorReporter'; +import { createQueue } from './utils/runQueue'; /* eslint-disable camelcase, no-undef */ const requireIndirect = typeof __webpack_require__ !== 'undefined' ? __webpack_require__ : require; @@ -29,6 +31,15 @@ const createHoc = (SourceComponent, TargetComponent) => { return TargetComponent; }; +const runInRequireQueue = createQueue(); +const runInRenderQueue = createQueue(cb => { + if (ReactDOM.unstable_batchedUpdates) { + ReactDOM.unstable_batchedUpdates(cb); + } else { + cb(); + } +}); + const makeHotExport = (sourceModule, moduleId) => { const updateInstances = possibleError => { if (possibleError && possibleError instanceof Error) { @@ -36,15 +47,20 @@ const makeHotExport = (sourceModule, moduleId) => { return; } const module = hotModule(moduleId); - clearTimeout(module.updateTimeout); - module.updateTimeout = setTimeout(() => { + + // require all modules + runInRequireQueue(() => { try { requireIndirect(moduleId); } catch (e) { console.error('React-Hot-Loader: error detected while loading', moduleId); console.error(e); } - module.instances.forEach(inst => inst.forceUpdate()); + }).then(() => { + // force flush all updates + runInRenderQueue(() => { + module.instances.forEach(inst => inst.forceUpdate()); + }); }); };