Add Offscreen component type
Doesn't do anything special in this initial commit. Just acts like a fragment.
Luna Ruan committed
Apr 23, 2020 at 12:53 UTC
ed01fdacceba20ffd004f0eae05ee07a6bb6a690
5 files changed
+58
-1
packages/react-reconciler/src/ReactFiber.new.js
+27
@@ -54,6 +54,7 @@ import {
54
FundamentalComponent,
55
ScopeComponent,
56
Block,
57
+ OffscreenComponent,
58
} from './ReactWorkTags';
59
import getComponentName from 'shared/getComponentName';
60
@@ -87,6 +88,7 @@ import {
88
REACT_FUNDAMENTAL_TYPE,
89
REACT_SCOPE_TYPE,
90
REACT_BLOCK_TYPE,
91
+ REACT_OFFSCREEN_TYPE,
92
} from 'shared/ReactSymbols';
93
94
export type {Fiber};
@@ -511,6 +513,13 @@ export function createFiberFromTypeAndProps(
513
expirationTime,
514
key,
515
);
516
+ case REACT_OFFSCREEN_TYPE:
517
+ return createFiberFromOffscreen(
518
+ pendingProps,
519
+ mode,
520
+ expirationTime,
521
+ key,
522
+ );
523
default: {
524
if (typeof type === 'object' && type !== null) {
525
switch (type.$$typeof) {
@@ -728,6 +737,24 @@ export function createFiberFromSuspenseList(
737
return fiber;
738
}
739
740
+export function createFiberFromOffscreen(
741
+ pendingProps: any,
742
+ mode: TypeOfMode,
743
+ expirationTime: ExpirationTimeOpaque,
744
+ key: null | string,
745
+) {
746
+ const fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
747
+ // TODO: The OffscreenComponent fiber shouldn't have a type. It has a tag.
748
+ // This needs to be fixed in getComponentName so that it relies on the tag
749
+ // instead.
750
+ if (__DEV__) {
751
+ fiber.type = REACT_OFFSCREEN_TYPE;
752
+ }
753
+ fiber.elementType = REACT_OFFSCREEN_TYPE;
754
+ fiber.expirationTime_opaque = expirationTime;
755
+ return fiber;
756
+}
757
+
758
export function createFiberFromText(
759
content: string,
760
mode: TypeOfMode,
packages/react-reconciler/src/ReactFiberBeginWork.new.js
+23
@@ -45,6 +45,7 @@ import {
45
FundamentalComponent,
46
ScopeComponent,
47
Block,
48
+ OffscreenComponent,
49
} from './ReactWorkTags';
50
import {
51
NoEffect,
@@ -555,6 +556,21 @@ function updateSimpleMemoComponent(
556
);
557
}
558
559
+function updateOffscreenComponent(
560
+ current: Fiber | null,
561
+ workInProgress: Fiber,
562
+ renderExpirationTime: ExpirationTimeOpaque,
563
+) {
564
+ const nextChildren = workInProgress.pendingProps;
565
+ reconcileChildren(
566
+ current,
567
+ workInProgress,
568
+ nextChildren,
569
+ renderExpirationTime,
570
+ );
571
+ return workInProgress.child;
572
+}
573
+
574
function updateFragment(
575
current: Fiber | null,
576
workInProgress: Fiber,
@@ -3448,6 +3464,13 @@ function beginWork(
3464
renderExpirationTime,
3465
);
3466
}
3467
+ case OffscreenComponent: {
3468
+ return updateOffscreenComponent(
3469
+ current,
3470
+ workInProgress,
3471
+ renderExpirationTime,
3472
+ );
3473
+ }
3474
case SimpleMemoComponent: {
3475
return updateSimpleMemoComponent(
3476
current,
packages/react-reconciler/src/ReactFiberCompleteWork.new.js
+3
@@ -53,6 +53,7 @@ import {
53
FundamentalComponent,
54
ScopeComponent,
55
Block,
56
+ OffscreenComponent,
57
} from './ReactWorkTags';
58
import {NoMode, BlockingMode} from './ReactTypeOfMode';
59
import {Ref, Update, NoEffect, DidCapture} from './ReactSideEffectTags';
@@ -1287,6 +1288,8 @@ function completeWork(
1288
return null;
1289
}
1290
break;
1291
+ case OffscreenComponent:
1292
+ return null;
1293
}
1294
invariant(
1295
false,
packages/react-reconciler/src/ReactWorkTags.js
+3
-1
@@ -30,7 +30,8 @@ export type WorkTag =
30
| 19
31
| 20
32
| 21
33
- | 22;
33
+ | 22
34
+ | 23;
35
36
export const FunctionComponent = 0;
37
export const ClassComponent = 1;
@@ -55,3 +56,4 @@ export const SuspenseListComponent = 19;
56
export const FundamentalComponent = 20;
57
export const ScopeComponent = 21;
58
export const Block = 22;
59
+export const OffscreenComponent = 23;
packages/shared/ReactSymbols.js
+2
@@ -32,6 +32,7 @@ export let REACT_RESPONDER_TYPE = 0xead6;
32
export let REACT_SCOPE_TYPE = 0xead7;
33
export let REACT_OPAQUE_ID_TYPE = 0xeae0;
34
export let REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
35
+export let REACT_OFFSCREEN_TYPE = 0xeae2;
36
37
if (typeof Symbol === 'function' && Symbol.for) {
38
const symbolFor = Symbol.for;
@@ -54,6 +55,7 @@ if (typeof Symbol === 'function' && Symbol.for) {
55
REACT_SCOPE_TYPE = symbolFor('react.scope');
56
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
57
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
58
+ REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
59
}
60
61
const MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;