@samitouri / QOS-React / commits / 95a313ec0b

Unfork Lazy Component Branches (#13902)

* Introduce elementType field This will be used to store the wrapped type of an element. E.g. pure and lazy. The existing type field will be used for the unwrapped type within them. * Store the unwrapped type on the type field of lazy components * Use the raw tags for lazy components Instead, we check if the elementType and type are equal to test if we need to resolve props. This is slightly slower in the normal case but will yield less code and branching. * Clean up lazy branches * Collapse work tag numbering * Split IndeterminateComponent out from Lazy This way we don't have to check the type in a hacky way in the indeterminate path. Also, lets us deal with lazy that resolves to indeterminate and such. * Missing clean up in rebase

Sebastian Markbåge committed Oct 19, 2018 at 22:22 UTC 95a313ec0b957f71798a69d8e83408f40e76765b
18 files changed +255 -359
packages/react-dom/src/test-utils/ReactTestUtils.js
+1 -5
@@ -11,9 +11,7 @@ import {findCurrentFiberUsingSlowPath} from 'react-reconciler/reflection';
11 import * as ReactInstanceMap from 'shared/ReactInstanceMap';
12 import {
13 ClassComponent,
14 - ClassComponentLazy,
14 FunctionComponent,
16 - FunctionComponentLazy,
15 HostComponent,
16 HostText,
17 } from 'shared/ReactWorkTags';
@@ -92,9 +90,7 @@ function findAllInRenderedFiberTreeInternal(fiber, test) {
90 node.tag === HostComponent ||
91 node.tag === HostText ||
92 node.tag === ClassComponent ||
95 - node.tag === ClassComponentLazy ||
96 - node.tag === FunctionComponent ||
97 - node.tag === FunctionComponentLazy
93 + node.tag === FunctionComponent
94 ) {
95 const publicInst = node.stateNode;
96 if (test(publicInst)) {
packages/react-reconciler/src/ReactChildFiber.js
+4 -7
@@ -23,7 +23,6 @@ import {
23 import {
24 FunctionComponent,
25 ClassComponent,
26 - ClassComponentLazy,
26 HostText,
27 HostPortal,
28 Fragment,
@@ -138,8 +137,7 @@ function coerceRef(
137 if (owner) {
138 const ownerFiber = ((owner: any): Fiber);
139 invariant(
141 - ownerFiber.tag === ClassComponent ||
142 - ownerFiber.tag === ClassComponentLazy,
140 + ownerFiber.tag === ClassComponent,
141 'Function components cannot have refs.',
142 );
143 inst = ownerFiber.stateNode;
@@ -379,7 +377,7 @@ function ChildReconciler(shouldTrackSideEffects) {
377 element: ReactElement,
378 expirationTime: ExpirationTime,
379 ): Fiber {
382 - if (current !== null && current.type === element.type) {
380 + if (current !== null && current.elementType === element.type) {
381 // Move based on index
382 const existing = useFiber(current, element.props, expirationTime);
383 existing.ref = coerceRef(returnFiber, current, element);
@@ -1122,7 +1120,7 @@ function ChildReconciler(shouldTrackSideEffects) {
1120 if (
1121 child.tag === Fragment
1122 ? element.type === REACT_FRAGMENT_TYPE
1125 - : child.type === element.type
1123 + : child.elementType === element.type
1124 ) {
1125 deleteRemainingChildren(returnFiber, child.sibling);
1126 const existing = useFiber(
@@ -1309,8 +1307,7 @@ function ChildReconciler(shouldTrackSideEffects) {
1307 // component, throw an error. If Fiber return types are disabled,
1308 // we already threw above.
1309 switch (returnFiber.tag) {
1312 - case ClassComponent:
1313 - case ClassComponentLazy: {
1310 + case ClassComponent: {
1311 if (__DEV__) {
1312 const instance = returnFiber.stateNode;
1313 if (instance.render._isMockFunction) {
packages/react-reconciler/src/ReactCurrentFiber.js
+2 -4
@@ -11,11 +11,10 @@ import ReactSharedInternals from 'shared/ReactSharedInternals';
11 import {
12 IndeterminateComponent,
13 FunctionComponent,
14 - FunctionComponentLazy,
14 ClassComponent,
16 - ClassComponentLazy,
15 HostComponent,
16 Mode,
17 + LazyComponent,
18 } from 'shared/ReactWorkTags';
19 import describeComponentFrame from 'shared/describeComponentFrame';
20 import getComponentName from 'shared/getComponentName';
@@ -29,10 +28,9 @@ type LifeCyclePhase = 'render' | 'getChildContext';
28 function describeFiber(fiber: Fiber): string {
29 switch (fiber.tag) {
30 case IndeterminateComponent:
31 + case LazyComponent:
32 case FunctionComponent:
33 - case FunctionComponentLazy:
33 case ClassComponent:
35 - case ClassComponentLazy:
34 case HostComponent:
35 case Mode:
36 const owner = fiber._debugOwner;
packages/react-reconciler/src/ReactFiber.js
+92 -25
@@ -34,11 +34,9 @@ import {
34 ContextConsumer,
35 Profiler,
36 SuspenseComponent,
37 - FunctionComponentLazy,
38 - ClassComponentLazy,
39 - ForwardRefLazy,
37 + FunctionComponent,
38 PureComponent,
41 - PureComponentLazy,
39 + LazyComponent,
40 } from 'shared/ReactWorkTags';
41 import getComponentName from 'shared/getComponentName';
42
@@ -101,7 +99,11 @@ export type Fiber = {|
99 // Unique identifier of this child.
100 key: null | string,
101
104 - // The function/class/module associated with this fiber.
102 + // The value of element.type which is used to preserve the identity during
103 + // reconciliation of this child.
104 + elementType: any,
105 +
106 + // The resolved function/class/ associated with this fiber.
107 type: any,
108
109 // The local state associated with this fiber.
@@ -219,6 +221,7 @@ function FiberNode(
221 // Instance
222 this.tag = tag;
223 this.key = key;
224 + this.elementType = null;
225 this.type = null;
226 this.stateNode = null;
227
@@ -301,16 +304,14 @@ export function resolveLazyComponentTag(
304 Component: Function,
305 ): WorkTag {
306 if (typeof Component === 'function') {
304 - return shouldConstruct(Component)
305 - ? ClassComponentLazy
306 - : FunctionComponentLazy;
307 + return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
308 } else if (Component !== undefined && Component !== null) {
309 const $$typeof = Component.$$typeof;
310 if ($$typeof === REACT_FORWARD_REF_TYPE) {
310 - return ForwardRefLazy;
311 + return ForwardRef;
312 }
313 if ($$typeof === REACT_PURE_TYPE) {
313 - return PureComponentLazy;
314 + return PureComponent;
315 }
316 }
317 return IndeterminateComponent;
@@ -335,6 +336,7 @@ export function createWorkInProgress(
336 current.key,
337 current.mode,
338 );
339 + workInProgress.elementType = current.elementType;
340 workInProgress.type = current.type;
341 workInProgress.stateNode = current.stateNode;
342
@@ -404,7 +406,7 @@ export function createHostRootFiber(isConcurrent: boolean): Fiber {
406 return createFiber(HostRoot, null, null, mode);
407 }
408
407 -export function createFiberFromElement(
409 +function createFiberFromElementWithoutDebugInfo(
410 element: ReactElement,
411 mode: TypeOfMode,
412 expirationTime: ExpirationTime,
@@ -419,9 +421,13 @@ export function createFiberFromElement(
421 const key = element.key;
422 const pendingProps = element.props;
423
422 - let fiberTag;
424 + let fiberTag = IndeterminateComponent;
425 + // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
426 + let resolvedType = type;
427 if (typeof type === 'function') {
424 - fiberTag = shouldConstruct(type) ? ClassComponent : IndeterminateComponent;
428 + if (shouldConstruct(type)) {
429 + fiberTag = ClassComponent;
430 + }
431 } else if (typeof type === 'string') {
432 fiberTag = HostComponent;
433 } else {
@@ -434,18 +440,23 @@ export function createFiberFromElement(
440 key,
441 );
442 case REACT_CONCURRENT_MODE_TYPE:
437 - fiberTag = Mode;
438 - mode |= ConcurrentMode | StrictMode;
439 - break;
443 + return createFiberFromMode(
444 + pendingProps,
445 + mode | ConcurrentMode | StrictMode,
446 + expirationTime,
447 + key,
448 + );
449 case REACT_STRICT_MODE_TYPE:
441 - fiberTag = Mode;
442 - mode |= StrictMode;
443 - break;
450 + return createFiberFromMode(
451 + pendingProps,
452 + mode | StrictMode,
453 + expirationTime,
454 + key,
455 + );
456 case REACT_PROFILER_TYPE:
457 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
458 case REACT_SUSPENSE_TYPE:
447 - fiberTag = SuspenseComponent;
448 - break;
459 + return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
460 default: {
461 if (typeof type === 'object' && type !== null) {
462 switch (type.$$typeof) {
@@ -463,7 +474,8 @@ export function createFiberFromElement(
474 fiberTag = PureComponent;
475 break getTag;
476 case REACT_LAZY_TYPE:
466 - fiberTag = IndeterminateComponent;
477 + fiberTag = LazyComponent;
478 + resolvedType = null;
479 break getTag;
480 }
481 }
@@ -498,14 +510,27 @@ export function createFiberFromElement(
510 }
511
512 fiber = createFiber(fiberTag, pendingProps, key, mode);
501 - fiber.type = type;
513 + fiber.elementType = type;
514 + fiber.type = resolvedType;
515 fiber.expirationTime = expirationTime;
516
517 + return fiber;
518 +}
519 +
520 +export function createFiberFromElement(
521 + element: ReactElement,
522 + mode: TypeOfMode,
523 + expirationTime: ExpirationTime,
524 +): Fiber {
525 + const fiber = createFiberFromElementWithoutDebugInfo(
526 + element,
527 + mode,
528 + expirationTime,
529 + );
530 if (__DEV__) {
531 fiber._debugSource = element._source;
532 fiber._debugOwner = element._owner;
533 }
508 -
534 return fiber;
535 }
536
@@ -520,7 +545,7 @@ export function createFiberFromFragment(
545 return fiber;
546 }
547
523 -export function createFiberFromProfiler(
548 +function createFiberFromProfiler(
549 pendingProps: any,
550 mode: TypeOfMode,
551 expirationTime: ExpirationTime,
@@ -539,12 +564,51 @@ export function createFiberFromProfiler(
564 }
565
566 const fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
567 + // TODO: The Profiler fiber shouldn't have a type. It has a tag.
568 + fiber.elementType = REACT_PROFILER_TYPE;
569 fiber.type = REACT_PROFILER_TYPE;
570 fiber.expirationTime = expirationTime;
571
572 return fiber;
573 }
574
575 +function createFiberFromMode(
576 + pendingProps: any,
577 + mode: TypeOfMode,
578 + expirationTime: ExpirationTime,
579 + key: null | string,
580 +): Fiber {
581 + const fiber = createFiber(Mode, pendingProps, key, mode);
582 +
583 + // TODO: The Mode fiber shouldn't have a type. It has a tag.
584 + const type =
585 + (mode & ConcurrentMode) === NoContext
586 + ? REACT_STRICT_MODE_TYPE
587 + : REACT_CONCURRENT_MODE_TYPE;
588 + fiber.elementType = type;
589 + fiber.type = type;
590 +
591 + fiber.expirationTime = expirationTime;
592 + return fiber;
593 +}
594 +
595 +export function createFiberFromSuspense(
596 + pendingProps: any,
597 + mode: TypeOfMode,
598 + expirationTime: ExpirationTime,
599 + key: null | string,
600 +) {
601 + const fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
602 +
603 + // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
604 + const type = REACT_SUSPENSE_TYPE;
605 + fiber.elementType = type;
606 + fiber.type = type;
607 +
608 + fiber.expirationTime = expirationTime;
609 + return fiber;
610 +}
611 +
612 export function createFiberFromText(
613 content: string,
614 mode: TypeOfMode,
@@ -557,6 +621,8 @@ export function createFiberFromText(
621
622 export function createFiberFromHostInstanceForDeletion(): Fiber {
623 const fiber = createFiber(HostComponent, null, null, NoContext);
624 + // TODO: These should not need a type.
625 + fiber.elementType = 'DELETED';
626 fiber.type = 'DELETED';
627 return fiber;
628 }
@@ -596,6 +662,7 @@ export function assignFiberPropertiesInDEV(
662
663 target.tag = source.tag;
664 target.key = source.key;
665 + target.elementType = source.elementType;
666 target.type = source.type;
667 target.stateNode = source.stateNode;
668 target.return = source.return;
packages/react-reconciler/src/ReactFiberBeginWork.js
+120 -144
@@ -18,15 +18,12 @@ import checkPropTypes from 'prop-types/checkPropTypes';
18 import {
19 IndeterminateComponent,
20 FunctionComponent,
21 - FunctionComponentLazy,
21 ClassComponent,
23 - ClassComponentLazy,
22 HostRoot,
23 HostComponent,
24 HostText,
25 HostPortal,
26 ForwardRef,
29 - ForwardRefLazy,
27 Fragment,
28 Mode,
29 ContextProvider,
@@ -34,7 +31,7 @@ import {
31 Profiler,
32 SuspenseComponent,
33 PureComponent,
37 - PureComponentLazy,
34 + LazyComponent,
35 } from 'shared/ReactWorkTags';
36 import {
37 NoEffect,
@@ -104,13 +101,11 @@ import {
101 updateClassInstance,
102 } from './ReactFiberClassComponent';
103 import {readLazyComponentType} from './ReactFiberLazyComponent';
107 -import {getResultFromResolvedLazyComponent} from 'shared/ReactLazyComponent';
104 import {
105 resolveLazyComponentTag,
106 createFiberFromFragment,
107 createWorkInProgress,
108 } from './ReactFiber';
113 -import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';
109
110 const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
111
@@ -705,10 +700,10 @@ function resolveDefaultProps(Component, baseProps) {
700 return baseProps;
701 }
702
708 -function mountIndeterminateComponent(
703 +function mountLazyComponent(
704 _current,
705 workInProgress,
711 - Component,
706 + elementType,
707 updateExpirationTime,
708 renderExpirationTime,
709 ) {
@@ -724,79 +719,94 @@ function mountIndeterminateComponent(
719 }
720
721 const props = workInProgress.pendingProps;
727 - if (
728 - typeof Component === 'object' &&
729 - Component !== null &&
730 - Component.$$typeof === REACT_LAZY_TYPE
731 - ) {
732 - // We can't start a User Timing measurement with correct label yet.
733 - // Cancel and resume right after we know the tag.
734 - cancelWorkTimer(workInProgress);
735 - Component = readLazyComponentType(Component);
736 - const resolvedTag = (workInProgress.tag = resolveLazyComponentTag(
737 - workInProgress,
738 - Component,
739 - ));
740 - startWorkTimer(workInProgress);
741 - const resolvedProps = resolveDefaultProps(Component, props);
742 - let child;
743 - switch (resolvedTag) {
744 - case FunctionComponentLazy: {
745 - child = updateFunctionComponent(
746 - null,
747 - workInProgress,
748 - Component,
749 - resolvedProps,
750 - renderExpirationTime,
751 - );
752 - break;
753 - }
754 - case ClassComponentLazy: {
755 - child = updateClassComponent(
756 - null,
757 - workInProgress,
758 - Component,
759 - resolvedProps,
760 - renderExpirationTime,
761 - );
762 - break;
763 - }
764 - case ForwardRefLazy: {
765 - child = updateForwardRef(
766 - null,
767 - workInProgress,
768 - Component,
769 - resolvedProps,
770 - renderExpirationTime,
771 - );
772 - break;
773 - }
774 - case PureComponentLazy: {
775 - child = updatePureComponent(
776 - null,
777 - workInProgress,
778 - Component,
779 - resolvedProps,
780 - updateExpirationTime,
781 - renderExpirationTime,
782 - );
783 - break;
784 - }
785 - default: {
786 - // This message intentionally doesn't metion ForwardRef or PureComponent
787 - // because the fact that it's a separate type of work is an
788 - // implementation detail.
789 - invariant(
790 - false,
791 - 'Element type is invalid. Received a promise that resolves to: %s. ' +
792 - 'Promise elements must resolve to a class or function.',
793 - Component,
794 - );
795 - }
722 + // We can't start a User Timing measurement with correct label yet.
723 + // Cancel and resume right after we know the tag.
724 + cancelWorkTimer(workInProgress);
725 + let Component = readLazyComponentType(elementType);
726 + // Store the unwrapped component in the type.
727 + workInProgress.type = Component;
728 + const resolvedTag = (workInProgress.tag = resolveLazyComponentTag(
729 + workInProgress,
730 + Component,
731 + ));
732 + startWorkTimer(workInProgress);
733 + const resolvedProps = resolveDefaultProps(Component, props);
734 + let child;
735 + switch (resolvedTag) {
736 + case FunctionComponent: {
737 + child = updateFunctionComponent(
738 + null,
739 + workInProgress,
740 + Component,
741 + resolvedProps,
742 + renderExpirationTime,
743 + );
744 + break;
745 + }
746 + case ClassComponent: {
747 + child = updateClassComponent(
748 + null,
749 + workInProgress,
750 + Component,
751 + resolvedProps,
752 + renderExpirationTime,
753 + );
754 + break;
755 + }
756 + case ForwardRef: {
757 + child = updateForwardRef(
758 + null,
759 + workInProgress,
760 + Component,
761 + resolvedProps,
762 + renderExpirationTime,
763 + );
764 + break;
765 + }
766 + case PureComponent: {
767 + child = updatePureComponent(
768 + null,
769 + workInProgress,
770 + Component,
771 + resolvedProps,
772 + updateExpirationTime,
773 + renderExpirationTime,
774 + );
775 + break;
776 + }
777 + default: {
778 + // This message intentionally doesn't metion ForwardRef or PureComponent
779 + // because the fact that it's a separate type of work is an
780 + // implementation detail.
781 + invariant(
782 + false,
783 + 'Element type is invalid. Received a promise that resolves to: %s. ' +
784 + 'Promise elements must resolve to a class or function.',
785 + Component,
786 + );
787 }
797 - return child;
788 + }
789 + return child;
790 +}
791 +
792 +function mountIndeterminateComponent(
793 + _current,
794 + workInProgress,
795 + Component,
796 + renderExpirationTime,
797 +) {
798 + if (_current !== null) {
799 + // An indeterminate component only mounts if it suspended inside a non-
800 + // concurrent tree, in an inconsistent state. We want to tree it like
801 + // a new mount, even though an empty version of it already committed.
802 + // Disconnect the alternate pointers.
803 + _current.alternate = null;
804 + workInProgress.alternate = null;
805 + // Since this is conceptually a new fiber, schedule a Placement effect
806 + workInProgress.effectTag |= Placement;
807 }
808
809 + const props = workInProgress.pendingProps;
810 const unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
811 const context = getMaskedContext(workInProgress, unmaskedContext);
812
@@ -1403,14 +1413,6 @@ function beginWork(
1413 }
1414 break;
1415 }
1406 - case ClassComponentLazy: {
1407 - const thenable = workInProgress.type;
1408 - const Component = getResultFromResolvedLazyComponent(thenable);
1409 - if (isLegacyContextProvider(Component)) {
1410 - pushLegacyContextProvider(workInProgress);
1411 - }
1412 - break;
1413 - }
1416 case HostPortal:
1417 pushHostContainer(
1418 workInProgress,
@@ -1460,62 +1462,53 @@ function beginWork(
1462
1463 switch (workInProgress.tag) {
1464 case IndeterminateComponent: {
1463 - const Component = workInProgress.type;
1465 + const elementType = workInProgress.elementType;
1466 return mountIndeterminateComponent(
1467 current,
1468 workInProgress,
1467 - Component,
1468 - updateExpirationTime,
1469 + elementType,
1470 renderExpirationTime,
1471 );
1472 }
1472 - case FunctionComponent: {
1473 - const Component = workInProgress.type;
1474 - const unresolvedProps = workInProgress.pendingProps;
1475 - return updateFunctionComponent(
1473 + case LazyComponent: {
1474 + const elementType = workInProgress.elementType;
1475 + return mountLazyComponent(
1476 current,
1477 workInProgress,
1478 - Component,
1479 - unresolvedProps,
1478 + elementType,
1479 + updateExpirationTime,
1480 renderExpirationTime,
1481 );
1482 }
1483 - case FunctionComponentLazy: {
1484 - const thenable = workInProgress.type;
1485 - const Component = getResultFromResolvedLazyComponent(thenable);
1483 + case FunctionComponent: {
1484 + const Component = workInProgress.type;
1485 const unresolvedProps = workInProgress.pendingProps;
1487 - const child = updateFunctionComponent(
1486 + const resolvedProps =
1487 + workInProgress.elementType === Component
1488 + ? unresolvedProps
1489 + : resolveDefaultProps(Component, unresolvedProps);
1490 + return updateFunctionComponent(
1491 current,
1492 workInProgress,
1493 Component,
1491 - resolveDefaultProps(Component, unresolvedProps),
1494 + resolvedProps,
1495 renderExpirationTime,
1496 );
1494 - return child;
1497 }
1498 case ClassComponent: {
1499 const Component = workInProgress.type;
1500 const unresolvedProps = workInProgress.pendingProps;
1501 + const resolvedProps =
1502 + workInProgress.elementType === Component
1503 + ? unresolvedProps
1504 + : resolveDefaultProps(Component, unresolvedProps);
1505 return updateClassComponent(
1506 current,
1507 workInProgress,
1508 Component,
1503 - unresolvedProps,
1504 - renderExpirationTime,
1505 - );
1506 - }
1507 - case ClassComponentLazy: {
1508 - const thenable = workInProgress.type;
1509 - const Component = getResultFromResolvedLazyComponent(thenable);
1510 - const unresolvedProps = workInProgress.pendingProps;
1511 - const child = updateClassComponent(
1512 - current,
1513 - workInProgress,
1514 - Component,
1515 - resolveDefaultProps(Component, unresolvedProps),
1509 + resolvedProps,
1510 renderExpirationTime,
1511 );
1518 - return child;
1512 }
1513 case HostRoot:
1514 return updateHostRoot(current, workInProgress, renderExpirationTime);
@@ -1537,27 +1530,19 @@ function beginWork(
1530 );
1531 case ForwardRef: {
1532 const type = workInProgress.type;
1533 + const unresolvedProps = workInProgress.pendingProps;
1534 + const resolvedProps =
1535 + workInProgress.elementType === type
1536 + ? unresolvedProps
1537 + : resolveDefaultProps(type, unresolvedProps);
1538 return updateForwardRef(
1539 current,
1540 workInProgress,
1541 type,
1544 - workInProgress.pendingProps,
1542 + resolvedProps,
1543 renderExpirationTime,
1544 );
1545 }
1548 - case ForwardRefLazy: {
1549 - const thenable = workInProgress.type;
1550 - const Component = getResultFromResolvedLazyComponent(thenable);
1551 - const unresolvedProps = workInProgress.pendingProps;
1552 - const child = updateForwardRef(
1553 - current,
1554 - workInProgress,
1555 - Component,
1556 - resolveDefaultProps(Component, unresolvedProps),
1557 - renderExpirationTime,
1558 - );
1559 - return child;
1560 - }
1546 case Fragment:
1547 return updateFragment(current, workInProgress, renderExpirationTime);
1548 case Mode:
@@ -1578,28 +1563,19 @@ function beginWork(
1563 );
1564 case PureComponent: {
1565 const type = workInProgress.type;
1566 + const unresolvedProps = workInProgress.pendingProps;
1567 + const resolvedProps =
1568 + workInProgress.elementType === type
1569 + ? unresolvedProps
1570 + : resolveDefaultProps(type, unresolvedProps);
1571 return updatePureComponent(
1572 current,
1573 workInProgress,
1574 type,
1585 - workInProgress.pendingProps,
1586 - updateExpirationTime,
1587 - renderExpirationTime,
1588 - );
1589 - }
1590 - case PureComponentLazy: {
1591 - const thenable = workInProgress.type;
1592 - const Component = getResultFromResolvedLazyComponent(thenable);
1593 - const unresolvedProps = workInProgress.pendingProps;
1594 - const child = updatePureComponent(
1595 - current,
1596 - workInProgress,
1597 - Component,
1598 - resolveDefaultProps(Component, unresolvedProps),
1575 + resolvedProps,
1576 updateExpirationTime,
1577 renderExpirationTime,
1578 );
1602 - return child;
1579 }
1580 default:
1581 invariant(
packages/react-reconciler/src/ReactFiberCommitWork.js
+5 -12
@@ -26,7 +26,6 @@ import {
26 } from 'shared/ReactFeatureFlags';
27 import {
28 ClassComponent,
29 - ClassComponentLazy,
29 HostRoot,
30 HostComponent,
31 HostText,
@@ -185,8 +184,7 @@ function commitBeforeMutationLifeCycles(
184 finishedWork: Fiber,
185 ): void {
186 switch (finishedWork.tag) {
188 - case ClassComponent:
189 - case ClassComponentLazy: {
187 + case ClassComponent: {
188 if (finishedWork.effectTag & Snapshot) {
189 if (current !== null) {
190 const prevProps = current.memoizedProps;
@@ -242,8 +240,7 @@ function commitLifeCycles(
240 committedExpirationTime: ExpirationTime,
241 ): void {
242 switch (finishedWork.tag) {
245 - case ClassComponent:
246 - case ClassComponentLazy: {
243 + case ClassComponent: {
244 const instance = finishedWork.stateNode;
245 if (finishedWork.effectTag & Update) {
246 if (current === null) {
@@ -289,7 +286,6 @@ function commitLifeCycles(
286 instance = getPublicInstance(finishedWork.child.stateNode);
287 break;
288 case ClassComponent:
292 - case ClassComponentLazy:
289 instance = finishedWork.child.stateNode;
290 break;
291 }
@@ -496,8 +492,7 @@ function commitUnmount(current: Fiber): void {
492 onCommitUnmount(current);
493
494 switch (current.tag) {
499 - case ClassComponent:
500 - case ClassComponentLazy: {
495 + case ClassComponent: {
496 safelyDetachRef(current);
497 const instance = current.stateNode;
498 if (typeof instance.componentWillUnmount === 'function') {
@@ -590,8 +585,7 @@ function commitContainer(finishedWork: Fiber) {
585 }
586
587 switch (finishedWork.tag) {
593 - case ClassComponent:
594 - case ClassComponentLazy: {
588 + case ClassComponent: {
589 return;
590 }
591 case HostComponent: {
@@ -876,8 +870,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
870 }
871
872 switch (finishedWork.tag) {
879 - case ClassComponent:
880 - case ClassComponentLazy: {
873 + case ClassComponent: {
874 return;
875 }
876 case HostComponent: {
packages/react-reconciler/src/ReactFiberCompleteWork.js
+3 -16
@@ -22,9 +22,7 @@ import type {SuspenseState} from './ReactFiberSuspenseComponent';
22 import {
23 IndeterminateComponent,
24 FunctionComponent,
25 - FunctionComponentLazy,
25 ClassComponent,
27 - ClassComponentLazy,
26 HostRoot,
27 HostComponent,
28 HostText,
@@ -36,13 +34,11 @@ import {
34 Mode,
35 Profiler,
36 SuspenseComponent,
39 - ForwardRefLazy,
37 PureComponent,
41 - PureComponentLazy,
38 + LazyComponent,
39 } from 'shared/ReactWorkTags';
40 import {Placement, Ref, Update} from 'shared/ReactSideEffectTags';
41 import invariant from 'shared/invariant';
45 -import {getResultFromResolvedLazyComponent} from 'shared/ReactLazyComponent';
42
43 import {
44 createInstance,
@@ -541,8 +537,9 @@ function completeWork(
537 switch (workInProgress.tag) {
538 case IndeterminateComponent:
539 break;
540 + case LazyComponent:
541 + break;
542 case FunctionComponent:
545 - case FunctionComponentLazy:
543 break;
544 case ClassComponent: {
545 const Component = workInProgress.type;
@@ -551,13 +548,6 @@ function completeWork(
548 }
549 break;
550 }
554 - case ClassComponentLazy: {
555 - const Component = getResultFromResolvedLazyComponent(workInProgress.type);
556 - if (isLegacyContextProvider(Component)) {
557 - popLegacyContext(workInProgress);
558 - }
559 - break;
560 - }
551 case HostRoot: {
552 popHostContainer(workInProgress);
553 popTopLevelLegacyContextObject(workInProgress);
@@ -694,8 +684,6 @@ function completeWork(
684 break;
685 }
686 case ForwardRef:
697 - case ForwardRefLazy:
698 - break;
687 case SuspenseComponent: {
688 const nextState = workInProgress.memoizedState;
689 const prevState = current !== null ? current.memoizedState : null;
@@ -725,7 +713,6 @@ function completeWork(
713 case ContextConsumer:
714 break;
715 case PureComponent:
728 - case PureComponentLazy:
716 break;
717 default:
718 invariant(
packages/react-reconciler/src/ReactFiberContext.js
+2 -15
@@ -11,16 +11,11 @@ import type {Fiber} from './ReactFiber';
11 import type {StackCursor} from './ReactFiberStack';
12
13 import {isFiberMounted} from 'react-reconciler/reflection';
14 -import {
15 - ClassComponent,
16 - HostRoot,
17 - ClassComponentLazy,
18 -} from 'shared/ReactWorkTags';
14 +import {ClassComponent, HostRoot} from 'shared/ReactWorkTags';
15 import getComponentName from 'shared/getComponentName';
16 import invariant from 'shared/invariant';
17 import warningWithoutStack from 'shared/warningWithoutStack';
18 import checkPropTypes from 'prop-types/checkPropTypes';
23 -import {getResultFromResolvedLazyComponent} from 'shared/ReactLazyComponent';
19
20 import * as ReactCurrentFiber from './ReactCurrentFiber';
21 import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
@@ -279,8 +274,7 @@ function findCurrentUnmaskedContext(fiber: Fiber): Object {
274 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
275 // makes sense elsewhere
276 invariant(
282 - isFiberMounted(fiber) &&
283 - (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy),
277 + isFiberMounted(fiber) && fiber.tag === ClassComponent,
278 'Expected subtree parent to be a mounted class component. ' +
279 'This error is likely caused by a bug in React. Please file an issue.',
280 );
@@ -297,13 +291,6 @@ function findCurrentUnmaskedContext(fiber: Fiber): Object {
291 }
292 break;
293 }
300 - case ClassComponentLazy: {
301 - const Component = getResultFromResolvedLazyComponent(node.type);
302 - if (isContextProvider(Component)) {
303 - return node.stateNode.__reactInternalMemoizedMergedChildContext;
304 - }
305 - break;
306 - }
294 }
295 node = node.return;
296 } while (node !== null);
packages/react-reconciler/src/ReactFiberNewContext.js
+2 -9
@@ -23,11 +23,7 @@ import {isPrimaryRenderer} from './ReactFiberHostConfig';
23 import {createCursor, push, pop} from './ReactFiberStack';
24 import maxSigned31BitInt from './maxSigned31BitInt';
25 import {NoWork} from './ReactFiberExpirationTime';
26 -import {
27 - ContextProvider,
28 - ClassComponent,
29 - ClassComponentLazy,
30 -} from 'shared/ReactWorkTags';
26 +import {ContextProvider, ClassComponent} from 'shared/ReactWorkTags';
27
28 import invariant from 'shared/invariant';
29 import warning from 'shared/warning';
@@ -163,10 +159,7 @@ export function propagateContextChange(
159 ) {
160 // Match! Schedule an update on this fiber.
161
166 - if (
167 - fiber.tag === ClassComponent ||
168 - fiber.tag === ClassComponentLazy
169 - ) {
162 + if (fiber.tag === ClassComponent) {
163 // Schedule a force update on the work-in-progress.
164 const update = createUpdate(renderExpirationTime);
165 update.tag = ForceUpdate;
packages/react-reconciler/src/ReactFiberReconciler.js
+1 -11
@@ -23,15 +23,10 @@ import {
23 findCurrentHostFiberWithNoPortals,
24 } from 'react-reconciler/reflection';
25 import * as ReactInstanceMap from 'shared/ReactInstanceMap';
26 -import {
27 - HostComponent,
28 - ClassComponent,
29 - ClassComponentLazy,
30 -} from 'shared/ReactWorkTags';
26 +import {HostComponent, ClassComponent} from 'shared/ReactWorkTags';
27 import getComponentName from 'shared/getComponentName';
28 import invariant from 'shared/invariant';
29 import warningWithoutStack from 'shared/warningWithoutStack';
34 -import {getResultFromResolvedLazyComponent} from 'shared/ReactLazyComponent';
30
31 import {getPublicInstance} from './ReactFiberHostConfig';
32 import {
@@ -106,11 +101,6 @@ function getContextForSubtree(
101 if (isLegacyContextProvider(Component)) {
102 return processChildContext(fiber, Component, parentContext);
103 }
109 - } else if (fiber.tag === ClassComponentLazy) {
110 - const Component = getResultFromResolvedLazyComponent(fiber.type);
111 - if (isLegacyContextProvider(Component)) {
112 - return processChildContext(fiber, Component, parentContext);
113 - }
104 }
105
106 return parentContext;
packages/react-reconciler/src/ReactFiberScheduler.js
+3 -21
@@ -38,7 +38,6 @@ import {
38 import {
39 HostRoot,
40 ClassComponent,
41 - ClassComponentLazy,
41 HostComponent,
42 ContextProvider,
43 HostPortal,
@@ -53,7 +52,6 @@ import {
52 import getComponentName from 'shared/getComponentName';
53 import invariant from 'shared/invariant';
54 import warningWithoutStack from 'shared/warningWithoutStack';
56 -import {getResultFromResolvedLazyComponent} from 'shared/ReactLazyComponent';
55
56 import {
57 scheduleTimeout,
@@ -316,15 +314,6 @@ if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
314 }
315 break;
316 }
319 - case ClassComponentLazy: {
320 - const Component = getResultFromResolvedLazyComponent(
321 - failedUnitOfWork.type,
322 - );
323 - if (isLegacyContextProvider(Component)) {
324 - popLegacyContext(failedUnitOfWork);
325 - }
326 - break;
327 - }
317 case HostPortal:
318 popHostContainer(failedUnitOfWork);
319 break;
@@ -1438,7 +1427,6 @@ function dispatch(
1427 while (fiber !== null) {
1428 switch (fiber.tag) {
1429 case ClassComponent:
1441 - case ClassComponentLazy:
1430 const ctor = fiber.type;
1431 const instance = fiber.stateNode;
1432 if (
@@ -1612,10 +1600,7 @@ function retrySuspendedRoot(
1600 // therefore does not have any pending work.
1601 scheduleWorkToRoot(sourceFiber, retryTime);
1602 const sourceTag = sourceFiber.tag;
1615 - if (
1616 - (sourceTag === ClassComponent || sourceFiber === ClassComponentLazy) &&
1617 - sourceFiber.stateNode !== null
1618 - ) {
1603 + if (sourceTag === ClassComponent && sourceFiber.stateNode !== null) {
1604 // When we try rendering again, we should not reuse the current fiber,
1605 // since it's known to be in an inconsistent state. Use a force updte to
1606 // prevent a bail out.
@@ -1635,7 +1620,7 @@ function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
1620 recordScheduleUpdate();
1621
1622 if (__DEV__) {
1638 - if (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy) {
1623 + if (fiber.tag === ClassComponent) {
1624 const instance = fiber.stateNode;
1625 warnAboutInvalidUpdates(instance);
1626 }
@@ -1692,10 +1677,7 @@ function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
1677 }
1678
1679 if (root === null) {
1695 - if (
1696 - __DEV__ &&
1697 - (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy)
1698 - ) {
1680 + if (__DEV__ && fiber.tag === ClassComponent) {
1681 warnAboutUpdateOnUnmounted(fiber);
1682 }
1683 return null;
packages/react-reconciler/src/ReactFiberTreeReflection.js
+1 -5
@@ -17,7 +17,6 @@ import ReactSharedInternals from 'shared/ReactSharedInternals';
17 import getComponentName from 'shared/getComponentName';
18 import {
19 ClassComponent,
20 - ClassComponentLazy,
20 HostComponent,
21 HostRoot,
22 HostPortal,
@@ -67,10 +66,7 @@ export function isFiberMounted(fiber: Fiber): boolean {
66 export function isMounted(component: React$Component<any, any>): boolean {
67 if (__DEV__) {
68 const owner = (ReactCurrentOwner.current: any);
70 - if (
71 - owner !== null &&
72 - (owner.tag === ClassComponent || owner.tag === ClassComponentLazy)
73 - ) {
69 + if (owner !== null && owner.tag === ClassComponent) {
70 const ownerFiber: Fiber = owner;
71 const instance = ownerFiber.stateNode;
72 warningWithoutStack(
packages/react-reconciler/src/ReactFiberUnwindWork.js
+1 -26
@@ -19,7 +19,6 @@ import getComponentName from 'shared/getComponentName';
19 import warningWithoutStack from 'shared/warningWithoutStack';
20 import {
21 ClassComponent,
22 - ClassComponentLazy,
22 HostRoot,
23 HostComponent,
24 HostPortal,
@@ -248,10 +247,7 @@ function throwException(
247 );
248 sourceFiber.effectTag &= ~Incomplete;
249
251 - if (
252 - sourceFiber.tag === ClassComponent ||
253 - sourceFiber.tag === ClassComponentLazy
254 - ) {
250 + if (sourceFiber.tag === ClassComponent) {
251 // We're going to commit this fiber even though it didn't
252 // complete. But we shouldn't call any lifecycle methods or
253 // callbacks. Remove all lifecycle effect tags.
@@ -341,7 +337,6 @@ function throwException(
337 return;
338 }
339 case ClassComponent:
344 - case ClassComponentLazy:
340 // Capture and retry
341 const errorInfo = value;
342 const ctor = workInProgress.type;
@@ -389,18 +384,6 @@ function unwindWork(
384 }
385 return null;
386 }
392 - case ClassComponentLazy: {
393 - const Component = workInProgress.type._reactResult;
394 - if (isLegacyContextProvider(Component)) {
395 - popLegacyContext(workInProgress);
396 - }
397 - const effectTag = workInProgress.effectTag;
398 - if (effectTag & ShouldCapture) {
399 - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture;
400 - return workInProgress;
401 - }
402 - return null;
403 - }
387 case HostRoot: {
388 popHostContainer(workInProgress);
389 popTopLevelLegacyContextObject(workInProgress);
@@ -471,14 +454,6 @@ function unwindInterruptedWork(interruptedWork: Fiber) {
454 }
455 break;
456 }
474 - case ClassComponentLazy: {
475 - const childContextTypes =
476 - interruptedWork.type._reactResult.childContextTypes;
477 - if (childContextTypes !== null && childContextTypes !== undefined) {
478 - popLegacyContext(interruptedWork);
479 - }
480 - break;
481 - }
457 case HostRoot: {
458 popHostContainer(interruptedWork);
459 popTopLevelLegacyContextObject(interruptedWork);
packages/react-reconciler/src/ReactUpdateQueue.js
+2 -2
@@ -89,7 +89,7 @@ import type {ExpirationTime} from './ReactFiberExpirationTime';
89
90 import {NoWork} from './ReactFiberExpirationTime';
91 import {Callback, ShouldCapture, DidCapture} from 'shared/ReactSideEffectTags';
92 -import {ClassComponent, ClassComponentLazy} from 'shared/ReactWorkTags';
92 +import {ClassComponent} from 'shared/ReactWorkTags';
93
94 import {
95 debugRenderPhaseSideEffects,
@@ -271,7 +271,7 @@ export function enqueueUpdate<State>(fiber: Fiber, update: Update<State>) {
271
272 if (__DEV__) {
273 if (
274 - (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy) &&
274 + fiber.tag === ClassComponent &&
275 (currentlyProcessingQueue === queue1 ||
276 (queue2 !== null && currentlyProcessingQueue === queue2)) &&
277 !didWarnUpdateInsideUpdate
packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
+1 -1
@@ -229,7 +229,7 @@ describe('ReactLazy', () => {
229 T.defaultProps = {text: 'Hi again'};
230 root.update(
231 <Suspense fallback={<Text text="Loading..." />}>
232 - <LazyText text="Hi again" />
232 + <LazyText />
233 </Suspense>,
234 );
235 expect(root).toFlushAndYield(['Hi again']);
packages/react-test-renderer/src/ReactTestRenderer.js
-32
@@ -17,9 +17,7 @@ import {findCurrentFiberUsingSlowPath} from 'react-reconciler/reflection';
17 import {
18 Fragment,
19 FunctionComponent,
20 - FunctionComponentLazy,
20 ClassComponent,
22 - ClassComponentLazy,
21 HostComponent,
22 HostPortal,
23 HostText,
@@ -29,9 +27,7 @@ import {
27 Mode,
28 ForwardRef,
29 Profiler,
32 - ForwardRefLazy,
30 PureComponent,
34 - PureComponentLazy,
31 } from 'shared/ReactWorkTags';
32 import invariant from 'shared/invariant';
33 import ReactVersion from 'shared/ReactVersion';
@@ -169,17 +165,6 @@ function toTree(node: ?Fiber) {
165 instance: node.stateNode,
166 rendered: childrenToTree(node.child),
167 };
172 - case ClassComponentLazy: {
173 - const thenable = node.type;
174 - const type = thenable._reactResult;
175 - return {
176 - nodeType: 'component',
177 - type,
178 - props: {...node.memoizedProps},
179 - instance: node.stateNode,
180 - rendered: childrenToTree(node.child),
181 - };
182 - }
168 case FunctionComponent:
169 return {
170 nodeType: 'component',
@@ -188,17 +173,6 @@ function toTree(node: ?Fiber) {
173 instance: null,
174 rendered: childrenToTree(node.child),
175 };
191 - case FunctionComponentLazy: {
192 - const thenable = node.type;
193 - const type = thenable._reactResult;
194 - return {
195 - nodeType: 'component',
196 - type: type,
197 - props: {...node.memoizedProps},
198 - instance: node.stateNode,
199 - rendered: childrenToTree(node.child),
200 - };
201 - }
176 case HostComponent: {
177 return {
178 nodeType: 'host',
@@ -216,9 +190,7 @@ function toTree(node: ?Fiber) {
190 case Mode:
191 case Profiler:
192 case ForwardRef:
219 - case ForwardRefLazy:
193 case PureComponent:
221 - case PureComponentLazy:
194 return childrenToTree(node.child);
195 default:
196 invariant(
@@ -231,14 +203,10 @@ function toTree(node: ?Fiber) {
203
204 const validWrapperTypes = new Set([
205 FunctionComponent,
234 - FunctionComponentLazy,
206 ClassComponent,
236 - ClassComponentLazy,
207 HostComponent,
208 ForwardRef,
239 - ForwardRefLazy,
209 PureComponent,
241 - PureComponentLazy,
210 // Normally skipped, but used when there's more than one root child.
211 HostRoot,
212 ]);
packages/shared/ReactLazyComponent.js
-6
@@ -29,12 +29,6 @@ export const Pending = 0;
29 export const Resolved = 1;
30 export const Rejected = 2;
31
32 -export function getResultFromResolvedLazyComponent<T>(
33 - lazyComponent: ResolvedLazyComponent<T>,
34 -): T {
35 - return lazyComponent._result;
36 -}
37 -
32 export function refineResolvedLazyComponent<T>(
33 lazyComponent: LazyComponent<T>,
34 ): ResolvedLazyComponent<T> | null {
packages/shared/ReactWorkTags.js
+15 -18
@@ -29,21 +29,18 @@ export type WorkTag =
29 | 18;
30
31 export const FunctionComponent = 0;
32 -export const FunctionComponentLazy = 1;
33 -export const ClassComponent = 2;
34 -export const ClassComponentLazy = 3;
35 -export const IndeterminateComponent = 4; // Before we know whether it is function or class
36 -export const HostRoot = 5; // Root of a host tree. Could be nested inside another node.
37 -export const HostPortal = 6; // A subtree. Could be an entry point to a different renderer.
38 -export const HostComponent = 7;
39 -export const HostText = 8;
40 -export const Fragment = 9;
41 -export const Mode = 10;
42 -export const ContextConsumer = 11;
43 -export const ContextProvider = 12;
44 -export const ForwardRef = 13;
45 -export const ForwardRefLazy = 14;
46 -export const Profiler = 15;
47 -export const SuspenseComponent = 16;
48 -export const PureComponent = 17;
49 -export const PureComponentLazy = 18;
32 +export const ClassComponent = 1;
33 +export const IndeterminateComponent = 2; // Before we know whether it is function or class
34 +export const HostRoot = 3; // Root of a host tree. Could be nested inside another node.
35 +export const HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
36 +export const HostComponent = 5;
37 +export const HostText = 6;
38 +export const Fragment = 7;
39 +export const Mode = 8;
40 +export const ContextConsumer = 9;
41 +export const ContextProvider = 10;
42 +export const ForwardRef = 11;
43 +export const Profiler = 12;
44 +export const SuspenseComponent = 13;
45 +export const PureComponent = 14;
46 +export const LazyComponent = 15;