Skip to content

Commit 8827a40

Browse files
committed
fix: react-dom hot-replacement is too active
1 parent af39ac1 commit 8827a40

File tree

4 files changed

+54
-31
lines changed

4 files changed

+54
-31
lines changed

Diff for: src/global/generation.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
let generation = 1
2+
let hotComparisonCounter = 0
23

3-
export const increment = () => generation++
4+
export const hotComparisonOpen = () => hotComparisonCounter > 0
5+
6+
const incrementHot = () => hotComparisonCounter++
7+
const decrementHot = () => hotComparisonCounter--
8+
9+
export const enterHotUpdate = () => {
10+
Promise.resolve(incrementHot()).then(decrementHot)
11+
}
12+
13+
export const increment = () => {
14+
enterHotUpdate()
15+
return generation++
16+
}
417
export const get = () => generation

Diff for: src/reactHotLoader.js

+37-29
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import {
88
isMemoType,
99
isForwardType,
1010
} from './internal/reactUtils'
11-
import { increment as incrementGeneration } from './global/generation'
11+
import {
12+
increment as incrementGeneration,
13+
hotComparisonOpen,
14+
enterHotUpdate,
15+
} from './global/generation'
1216
import {
1317
updateProxyById,
1418
resetProxies,
@@ -41,6 +45,8 @@ const updateLazy = (target, type) => {
4145
target[lazyConstructor] = () =>
4246
ctor().then(m => {
4347
const C = resolveType(m.default)
48+
// chunks has been updated - new hot loader process is taking a place
49+
enterHotUpdate()
4450
return {
4551
default: props => (
4652
<AppContainer>
@@ -64,40 +70,42 @@ export const hotComponentCompare = (oldType, newType, setNewType) => {
6470
return true
6571
}
6672

67-
if (
68-
(isRegisteredComponent(oldType) || isRegisteredComponent(newType)) &&
69-
resolveType(oldType) !== resolveType(newType)
70-
) {
71-
return false
72-
}
73+
if (hotComparisonOpen()) {
74+
if (
75+
(isRegisteredComponent(oldType) || isRegisteredComponent(newType)) &&
76+
resolveType(oldType) !== resolveType(newType)
77+
) {
78+
return false
79+
}
7380

74-
if (isForwardType({ type: oldType }) && isForwardType({ type: newType })) {
75-
if (areSwappable(oldType.render, newType.render)) {
76-
setNewType(newType)
77-
return true
81+
if (isForwardType({ type: oldType }) && isForwardType({ type: newType })) {
82+
if (areSwappable(oldType.render, newType.render)) {
83+
setNewType(newType)
84+
return true
85+
}
86+
return false
7887
}
79-
return false
80-
}
8188

82-
if (isMemoType({ type: oldType }) && isMemoType({ type: newType })) {
83-
if (areSwappable(oldType.type, newType.type)) {
84-
setNewType(newType.type)
85-
return true
89+
if (isMemoType({ type: oldType }) && isMemoType({ type: newType })) {
90+
if (areSwappable(oldType.type, newType.type)) {
91+
setNewType(newType.type)
92+
return true
93+
}
94+
return false
8695
}
87-
return false
88-
}
8996

90-
if (areSwappable(newType, oldType)) {
91-
const unwrapFactory = newType[UNWRAP_PROXY]
92-
const oldProxy = unwrapFactory && getProxyByType(unwrapFactory())
93-
if (oldProxy) {
94-
oldProxy.dereference()
95-
updateProxyById(oldType[PROXY_KEY], newType[UNWRAP_PROXY]())
96-
updateProxyById(newType[PROXY_KEY], oldType[UNWRAP_PROXY]())
97-
} else {
98-
setNewType(newType)
97+
if (areSwappable(newType, oldType)) {
98+
const unwrapFactory = newType[UNWRAP_PROXY]
99+
const oldProxy = unwrapFactory && getProxyByType(unwrapFactory())
100+
if (oldProxy) {
101+
oldProxy.dereference()
102+
updateProxyById(oldType[PROXY_KEY], newType[UNWRAP_PROXY]())
103+
updateProxyById(newType[PROXY_KEY], oldType[UNWRAP_PROXY]())
104+
} else {
105+
setNewType(newType)
106+
}
107+
return true
99108
}
100-
return true
101109
}
102110

103111
return false

Diff for: src/reconciler/proxies.js

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const updateProxyById = (id, type, options = {}) => {
5858
options,
5959
),
6060
)
61+
registerComponent(proxiesByID[id].get())
6162
} else {
6263
proxiesByID[id].update(type)
6364
}

Diff for: src/reconciler/proxyAdapter.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import reactHotLoader from '../reactHotLoader'
2-
import { get as getGeneration } from '../global/generation'
2+
import { enterHotUpdate, get as getGeneration } from '../global/generation'
33
import { getProxyByType, setStandInOptions } from './proxies'
44
import reconcileHotReplacement, {
55
flushScheduledUpdates,
@@ -20,6 +20,7 @@ export const renderReconciler = (target, force) => {
2020
(componentGeneration || force) &&
2121
componentGeneration !== currentGeneration
2222
) {
23+
enterHotUpdate()
2324
reconcileHotReplacement(target)
2425
return true
2526
}

0 commit comments

Comments
 (0)