Skip to content

Commit 33c54f5

Browse files
committed
fix: autodetect underupdated state and trigger an automatic update, fixes #1342
1 parent 62bc67e commit 33c54f5

File tree

4 files changed

+32
-12
lines changed

4 files changed

+32
-12
lines changed

src/configuration.js

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ const configuration = {
5454

5555
// Global error overlay
5656
ErrorOverlay: undefined,
57+
58+
// react hot dom features enabled
59+
IS_REACT_MERGE_ENABLED: false,
5760
};
5861

5962
export const internalConfiguration = {

src/hot.dev.js

+25-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { isOpened as isModuleOpened, hotModule, getLastModuleOpened } from './gl
88
import logger from './logger';
99
import { clearExceptions, logException } from './errorReporter';
1010
import { createQueue } from './utils/runQueue';
11+
import { enterHotUpdate, getHotGeneration } from './global/generation';
1112

1213
/* eslint-disable camelcase, no-undef */
1314
const requireIndirect = typeof __webpack_require__ !== 'undefined' ? __webpack_require__ : require;
@@ -48,6 +49,29 @@ const makeHotExport = (sourceModule, moduleId) => {
4849
}
4950
const module = hotModule(moduleId);
5051

52+
const deepUpdate = () => {
53+
// force flush all updates
54+
runInRenderQueue(() => {
55+
enterHotUpdate();
56+
const gen = getHotGeneration();
57+
module.instances.forEach(inst => inst.forceUpdate());
58+
59+
let runLimit = 0;
60+
const checkTailUpdates = () => {
61+
setTimeout(() => {
62+
if (getHotGeneration() !== gen) {
63+
console.warn('React-Hot-Loader has detected a stale state. Updating...');
64+
deepUpdate();
65+
} else if (++runLimit < 5) {
66+
checkTailUpdates();
67+
}
68+
}, 16);
69+
};
70+
71+
checkTailUpdates();
72+
});
73+
};
74+
5175
// require all modules
5276
runInRequireQueue(() => {
5377
try {
@@ -58,12 +82,7 @@ const makeHotExport = (sourceModule, moduleId) => {
5882
console.error('React-Hot-Loader: error detected while loading', moduleId);
5983
console.error(e);
6084
}
61-
}).then(() => {
62-
// force flush all updates
63-
runInRenderQueue(() => {
64-
module.instances.forEach(inst => inst.forceUpdate());
65-
});
66-
});
85+
}).then(deepUpdate);
6786
};
6887

6988
if (sourceModule.hot) {

src/reactHotLoader.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ const hookWrapper = hook => {
5757
const noDeps = () => [];
5858

5959
const reactHotLoader = {
60-
IS_REACT_MERGE_ENABLED: false,
6160
signature(type, key, getCustomHooks = noDeps) {
6261
addSignature(type, { key, getCustomHooks });
6362
return type;
@@ -75,7 +74,7 @@ const reactHotLoader = {
7574
const proxy = getProxyById(id);
7675

7776
if (proxy && proxy.getCurrent() !== type) {
78-
if (!reactHotLoader.IS_REACT_MERGE_ENABLED) {
77+
if (!configuration.IS_REACT_MERGE_ENABLED) {
7978
if (isTypeBlacklisted(type) || isTypeBlacklisted(proxy.getCurrent())) {
8079
logger.error('React-hot-loader: Cold component', uniqueLocalName, 'at', fileName, 'has been updated');
8180
}
@@ -146,7 +145,7 @@ const reactHotLoader = {
146145

147146
configuration.ignoreSFC = configuration.ignoreSFCWhenInjected;
148147

149-
reactHotLoader.IS_REACT_MERGE_ENABLED = true;
148+
configuration.IS_REACT_MERGE_ENABLED = true;
150149
configuration.showReactDomPatchNotification = false;
151150
configuration.integratedComparator = true;
152151

src/reconciler/hotReplacementRender.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
isLazyType,
1414
isForwardType,
1515
} from '../internal/reactUtils';
16-
import reactHotLoader from '../reactHotLoader';
1716
import logger from '../logger';
1817
import configuration, { internalConfiguration } from '../configuration';
1918
import { areSwappable } from './utils';
@@ -142,7 +141,7 @@ const mergeInject = (a, b, instance) => {
142141
}
143142
if (flatB.length === 0 && flatA.length === 1 && typeof flatA[0] !== 'object') {
144143
// terminal node
145-
} else if (!reactHotLoader.IS_REACT_MERGE_ENABLED) {
144+
} else if (!configuration.IS_REACT_MERGE_ENABLED) {
146145
logger.warn(`React-hot-loader: unable to merge `, a, 'and children of ', instance);
147146
stackReport();
148147
}
@@ -312,7 +311,7 @@ const hotReplacementRender = (instance, stack) => {
312311
}
313312

314313
if (!stackChild.type[PROXY_KEY]) {
315-
if (!reactHotLoader.IS_REACT_MERGE_ENABLED) {
314+
if (!configuration.IS_REACT_MERGE_ENABLED) {
316315
if (isTypeBlacklisted(stackChild.type)) {
317316
logger.warn('React-hot-loader: cold element got updated ', stackChild.type);
318317
}

0 commit comments

Comments
 (0)