@@ -22,6 +22,7 @@ import reactHotLoader from '../reactHotLoader'
22
22
import logger from '../logger'
23
23
import configuration , { internalConfiguration } from '../configuration'
24
24
import { areSwappable } from './utils'
25
+ import { resolveType } from './resolver'
25
26
26
27
let renderStack = [ ]
27
28
@@ -224,6 +225,7 @@ const hotReplacementRender = (instance, stack) => {
224
225
const { children } = stack
225
226
226
227
flow . forEach ( ( child , index ) => {
228
+ let childType = child . type
227
229
const stackChild = children [ index ]
228
230
const next = instance => {
229
231
// copy over props as long new component may be hidden inside them
@@ -258,12 +260,13 @@ const hotReplacementRender = (instance, stack) => {
258
260
return
259
261
}
260
262
261
- if ( typeof child . type !== typeof stackChild . type ) {
263
+ // comparing rendered type to fiber.ElementType
264
+ if ( typeof childType !== typeof stackChild . elementType ) {
262
265
// Portals could generate undefined !== null
263
- if ( child . type && stackChild . type ) {
266
+ if ( childType && stackChild . type ) {
264
267
logger . warn (
265
268
'React-hot-loader: got ' ,
266
- child . type ,
269
+ childType ,
267
270
'instead of' ,
268
271
stackChild . type ,
269
272
)
@@ -277,6 +280,7 @@ const hotReplacementRender = (instance, stack) => {
277
280
if ( stackChild . children && stackChild . children [ 0 ] ) {
278
281
scheduleInstanceUpdate ( stackChild . children [ 0 ] . instance )
279
282
}
283
+ childType = childType . type || childType
280
284
}
281
285
282
286
if ( isForwardType ( child ) ) {
@@ -285,24 +289,22 @@ const hotReplacementRender = (instance, stack) => {
285
289
try {
286
290
next ( {
287
291
children : ( child . props ? child . props . children : child . children [ 0 ] ) (
288
- stackContext ( ) . get ( getContextProvider ( child . type ) ) ||
289
- child . type [ CONTEXT_CURRENT_VALUE ] ,
292
+ stackContext ( ) . get ( getContextProvider ( childType ) ) ||
293
+ childType [ CONTEXT_CURRENT_VALUE ] ,
290
294
) ,
291
295
} )
292
296
} catch ( e ) {
293
297
// do nothing, yet
294
298
}
295
- } else if ( typeof child . type !== 'function' ) {
299
+ } else if ( typeof childType !== 'function' ) {
296
300
// React
297
- let childName = child . type
298
- ? getComponentDisplayName ( child . type )
299
- : 'empty'
301
+ let childName = childType ? getComponentDisplayName ( childType ) : 'empty'
300
302
let extraContext = stackContext ( )
301
303
302
304
if ( isContextProvider ( child ) ) {
303
305
extraContext = new Map ( extraContext )
304
306
extraContext . set (
305
- getContextProvider ( child . type ) ,
307
+ getContextProvider ( childType ) ,
306
308
{
307
309
...( child . nextProps || { } ) ,
308
310
...( child . props || { } ) ,
@@ -313,7 +315,7 @@ const hotReplacementRender = (instance, stack) => {
313
315
314
316
renderStack . push ( {
315
317
name : childName ,
316
- type : child . type ,
318
+ type : childType ,
317
319
props : stack . instance . props ,
318
320
context : extraContext ,
319
321
} )
@@ -330,11 +332,16 @@ const hotReplacementRender = (instance, stack) => {
330
332
)
331
333
renderStack . pop ( )
332
334
} else {
333
- if ( child . type === stackChild . type ) {
335
+ if ( childType === stackChild . type ) {
334
336
next ( stackChild . instance )
335
337
} else {
336
338
// unwrap proxy
337
- const childType = getElementType ( child )
339
+ let childType = getElementType ( child )
340
+
341
+ if ( isMemoType ( child ) ) {
342
+ childType = childType . type || childType
343
+ }
344
+
338
345
if ( ! stackChild . type [ PROXY_KEY ] ) {
339
346
if ( ! reactHotLoader . IS_REACT_MERGE_ENABLED ) {
340
347
if ( isTypeBlacklisted ( stackChild . type ) ) {
@@ -351,6 +358,11 @@ const hotReplacementRender = (instance, stack) => {
351
358
isRegisteredComponent ( stackChild . type )
352
359
) {
353
360
// one of elements are registered via babel plugin, and should not be handled by hot swap
361
+ if ( resolveType ( childType ) === resolveType ( stackChild . type ) ) {
362
+ next ( stackChild . instance )
363
+ } else {
364
+ // one component replace another. This is normal situation
365
+ }
354
366
} else if ( areSwappable ( childType , stackChild . type ) ) {
355
367
// they are both registered, or have equal code/displayname/signature
356
368
0 commit comments