8
*/
9
10
import type {ReactElement} from 'shared/ReactElementType';
11
-import type {ReactCall, ReactPortal, ReactReturn} from 'shared/ReactTypes';
11
+import type {ReactPortal} from 'shared/ReactTypes';
12
import type {Fiber} from 'react-reconciler/src/ReactFiber';
13
import type {ExpirationTime} from 'react-reconciler/src/ReactFiberExpirationTime';
14
17
getIteratorFn,
18
REACT_ELEMENT_TYPE,
19
REACT_FRAGMENT_TYPE,
20
- REACT_CALL_TYPE,
21
- REACT_RETURN_TYPE,
20
REACT_PORTAL_TYPE,
21
} from 'shared/ReactSymbols';
22
import {
24
ClassComponent,
25
HostText,
26
HostPortal,
29
- CallComponent,
30
- ReturnComponent,
27
Fragment,
28
} from 'shared/ReactTypeOfWork';
29
import emptyObject from 'fbjs/lib/emptyObject';
35
createFiberFromElement,
36
createFiberFromFragment,
37
createFiberFromText,
42
- createFiberFromCall,
43
- createFiberFromReturn,
38
createFiberFromPortal,
39
} from './ReactFiber';
40
import ReactDebugCurrentFiber from './ReactDebugCurrentFiber';
357
}
358
}
359
366
- function updateCall(
367
- returnFiber: Fiber,
368
- current: Fiber | null,
369
- call: ReactCall,
370
- expirationTime: ExpirationTime,
371
- ): Fiber {
372
- // TODO: Should this also compare handler to determine whether to reuse?
373
- if (current === null || current.tag !== CallComponent) {
374
- // Insert
375
- const created = createFiberFromCall(
376
- call,
377
- returnFiber.internalContextTag,
378
- expirationTime,
379
- );
380
- created.return = returnFiber;
381
- return created;
382
- } else {
383
- // Move based on index
384
- const existing = useFiber(current, call, expirationTime);
385
- existing.return = returnFiber;
386
- return existing;
387
- }
388
- }
389
-
390
- function updateReturn(
391
- returnFiber: Fiber,
392
- current: Fiber | null,
393
- returnNode: ReactReturn,
394
- expirationTime: ExpirationTime,
395
- ): Fiber {
396
- if (current === null || current.tag !== ReturnComponent) {
397
- // Insert
398
- const created = createFiberFromReturn(
399
- returnNode,
400
- returnFiber.internalContextTag,
401
- expirationTime,
402
- );
403
- created.type = returnNode.value;
404
- created.return = returnFiber;
405
- return created;
406
- } else {
407
- // Move based on index
408
- const existing = useFiber(current, null, expirationTime);
409
- existing.type = returnNode.value;
410
- existing.return = returnFiber;
411
- return existing;
412
- }
413
- }
414
-
360
function updatePortal(
361
returnFiber: Fiber,
362
current: Fiber | null,
431
if (typeof newChild === 'object' && newChild !== null) {
432
switch (newChild.$$typeof) {
433
case REACT_ELEMENT_TYPE: {
489
- if (newChild.type === REACT_FRAGMENT_TYPE) {
490
- const created = createFiberFromFragment(
491
- newChild.props.children,
492
- returnFiber.internalContextTag,
493
- expirationTime,
494
- newChild.key,
495
- );
496
- created.return = returnFiber;
497
- return created;
498
- } else {
499
- const created = createFiberFromElement(
500
- newChild,
501
- returnFiber.internalContextTag,
502
- expirationTime,
503
- );
504
- created.ref = coerceRef(null, newChild);
505
- created.return = returnFiber;
506
- return created;
507
- }
508
- }
509
-
510
- case REACT_CALL_TYPE: {
511
- const created = createFiberFromCall(
434
+ const created = createFiberFromElement(
435
newChild,
436
returnFiber.internalContextTag,
437
expirationTime,
438
);
439
+ created.ref = coerceRef(null, newChild);
440
created.return = returnFiber;
441
return created;
442
}
519
-
520
- case REACT_RETURN_TYPE: {
521
- const created = createFiberFromReturn(
522
- newChild,
523
- returnFiber.internalContextTag,
524
- expirationTime,
525
- );
526
- created.type = newChild.value;
527
- created.return = returnFiber;
528
- return created;
529
- }
530
-
443
case REACT_PORTAL_TYPE: {
444
const created = createFiberFromPortal(
445
newChild,
522
return null;
523
}
524
}
613
-
614
- case REACT_CALL_TYPE: {
615
- if (newChild.key === key) {
616
- return updateCall(returnFiber, oldFiber, newChild, expirationTime);
617
- } else {
618
- return null;
619
- }
620
- }
621
-
622
- case REACT_RETURN_TYPE: {
623
- // Returns don't have keys. If the previous node is implicitly keyed
624
- // we can continue to replace it without aborting even if it is not a
625
- // yield.
626
- if (key === null) {
627
- return updateReturn(
628
- returnFiber,
629
- oldFiber,
630
- newChild,
631
- expirationTime,
632
- );
633
- } else {
634
- return null;
635
- }
636
- }
637
-
525
case REACT_PORTAL_TYPE: {
526
if (newChild.key === key) {
527
return updatePortal(
604
expirationTime,
605
);
606
}
720
-
721
- case REACT_CALL_TYPE: {
722
- const matchedFiber =
723
- existingChildren.get(
724
- newChild.key === null ? newIdx : newChild.key,
725
- ) || null;
726
- return updateCall(
727
- returnFiber,
728
- matchedFiber,
729
- newChild,
730
- expirationTime,
731
- );
732
- }
733
-
734
- case REACT_RETURN_TYPE: {
735
- // Returns don't have keys, so we neither have to check the old nor
736
- // new node for the key. If both are returns, they match.
737
- const matchedFiber = existingChildren.get(newIdx) || null;
738
- return updateReturn(
739
- returnFiber,
740
- matchedFiber,
741
- newChild,
742
- expirationTime,
743
- );
744
- }
745
-
607
case REACT_PORTAL_TYPE: {
608
const matchedFiber =
609
existingChildren.get(
654
}
655
switch (child.$$typeof) {
656
case REACT_ELEMENT_TYPE:
796
- case REACT_CALL_TYPE:
657
case REACT_PORTAL_TYPE:
658
warnForMissingKey(child);
659
const key = child.key;
1112
}
1113
}
1114
1255
- function reconcileSingleCall(
1256
- returnFiber: Fiber,
1257
- currentFirstChild: Fiber | null,
1258
- call: ReactCall,
1259
- expirationTime: ExpirationTime,
1260
- ): Fiber {
1261
- const key = call.key;
1262
- let child = currentFirstChild;
1263
- while (child !== null) {
1264
- // TODO: If key === null and child.key === null, then this only applies to
1265
- // the first item in the list.
1266
- if (child.key === key) {
1267
- if (child.tag === CallComponent) {
1268
- deleteRemainingChildren(returnFiber, child.sibling);
1269
- const existing = useFiber(child, call, expirationTime);
1270
- existing.return = returnFiber;
1271
- return existing;
1272
- } else {
1273
- deleteRemainingChildren(returnFiber, child);
1274
- break;
1275
- }
1276
- } else {
1277
- deleteChild(returnFiber, child);
1278
- }
1279
- child = child.sibling;
1280
- }
1281
-
1282
- const created = createFiberFromCall(
1283
- call,
1284
- returnFiber.internalContextTag,
1285
- expirationTime,
1286
- );
1287
- created.return = returnFiber;
1288
- return created;
1289
- }
1290
-
1291
- function reconcileSingleReturn(
1292
- returnFiber: Fiber,
1293
- currentFirstChild: Fiber | null,
1294
- returnNode: ReactReturn,
1295
- expirationTime: ExpirationTime,
1296
- ): Fiber {
1297
- // There's no need to check for keys on yields since they're stateless.
1298
- let child = currentFirstChild;
1299
- if (child !== null) {
1300
- if (child.tag === ReturnComponent) {
1301
- deleteRemainingChildren(returnFiber, child.sibling);
1302
- const existing = useFiber(child, null, expirationTime);
1303
- existing.type = returnNode.value;
1304
- existing.return = returnFiber;
1305
- return existing;
1306
- } else {
1307
- deleteRemainingChildren(returnFiber, child);
1308
- }
1309
- }
1310
-
1311
- const created = createFiberFromReturn(
1312
- returnNode,
1313
- returnFiber.internalContextTag,
1314
- expirationTime,
1315
- );
1316
- created.type = returnNode.value;
1317
- created.return = returnFiber;
1318
- return created;
1319
- }
1320
-
1115
function reconcileSinglePortal(
1116
returnFiber: Fiber,
1117
currentFirstChild: Fiber | null,
1196
expirationTime,
1197
),
1198
);
1405
-
1406
- case REACT_CALL_TYPE:
1407
- return placeSingleChild(
1408
- reconcileSingleCall(
1409
- returnFiber,
1410
- currentFirstChild,
1411
- newChild,
1412
- expirationTime,
1413
- ),
1414
- );
1415
- case REACT_RETURN_TYPE:
1416
- return placeSingleChild(
1417
- reconcileSingleReturn(
1418
- returnFiber,
1419
- currentFirstChild,
1420
- newChild,
1421
- expirationTime,
1422
- ),
1423
- );
1199
case REACT_PORTAL_TYPE:
1200
return placeSingleChild(
1201
reconcileSinglePortal(