From ed01fdacceba20ffd004f0eae05ee07a6bb6a690 Mon Sep 17 00:00:00 2001 From: Luna Ruan Date: Thu, 23 Apr 2020 12:53:46 -0700 Subject: [PATCH] Add Offscreen component type Doesn't do anything special in this initial commit. Just acts like a fragment. --- .../react-reconciler/src/ReactFiber.new.js | 27 +++++++++++++++++++ .../src/ReactFiberBeginWork.new.js | 23 ++++++++++++++++ .../src/ReactFiberCompleteWork.new.js | 3 +++ .../react-reconciler/src/ReactWorkTags.js | 4 ++- packages/shared/ReactSymbols.js | 2 ++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/ReactFiber.new.js b/packages/react-reconciler/src/ReactFiber.new.js index 21f3aac972..d3332a8a60 100644 --- a/packages/react-reconciler/src/ReactFiber.new.js +++ b/packages/react-reconciler/src/ReactFiber.new.js @@ -54,6 +54,7 @@ import { FundamentalComponent, ScopeComponent, Block, + OffscreenComponent, } from './ReactWorkTags'; import getComponentName from 'shared/getComponentName'; @@ -87,6 +88,7 @@ import { REACT_FUNDAMENTAL_TYPE, REACT_SCOPE_TYPE, REACT_BLOCK_TYPE, + REACT_OFFSCREEN_TYPE, } from 'shared/ReactSymbols'; export type {Fiber}; @@ -511,6 +513,13 @@ export function createFiberFromTypeAndProps( expirationTime, key, ); + case REACT_OFFSCREEN_TYPE: + return createFiberFromOffscreen( + pendingProps, + mode, + expirationTime, + key, + ); default: { if (typeof type === 'object' && type !== null) { switch (type.$$typeof) { @@ -728,6 +737,24 @@ export function createFiberFromSuspenseList( return fiber; } +export function createFiberFromOffscreen( + pendingProps: any, + mode: TypeOfMode, + expirationTime: ExpirationTimeOpaque, + key: null | string, +) { + const fiber = createFiber(OffscreenComponent, pendingProps, key, mode); + // TODO: The OffscreenComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + if (__DEV__) { + fiber.type = REACT_OFFSCREEN_TYPE; + } + fiber.elementType = REACT_OFFSCREEN_TYPE; + fiber.expirationTime_opaque = expirationTime; + return fiber; +} + export function createFiberFromText( content: string, mode: TypeOfMode, diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index cffb27596d..ecdb87cea2 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -45,6 +45,7 @@ import { FundamentalComponent, ScopeComponent, Block, + OffscreenComponent, } from './ReactWorkTags'; import { NoEffect, @@ -555,6 +556,21 @@ function updateSimpleMemoComponent( ); } +function updateOffscreenComponent( + current: Fiber | null, + workInProgress: Fiber, + renderExpirationTime: ExpirationTimeOpaque, +) { + const nextChildren = workInProgress.pendingProps; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime, + ); + return workInProgress.child; +} + function updateFragment( current: Fiber | null, workInProgress: Fiber, @@ -3448,6 +3464,13 @@ function beginWork( renderExpirationTime, ); } + case OffscreenComponent: { + return updateOffscreenComponent( + current, + workInProgress, + renderExpirationTime, + ); + } case SimpleMemoComponent: { return updateSimpleMemoComponent( current, diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js index 775294b62d..e6fa333510 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js @@ -53,6 +53,7 @@ import { FundamentalComponent, ScopeComponent, Block, + OffscreenComponent, } from './ReactWorkTags'; import {NoMode, BlockingMode} from './ReactTypeOfMode'; import {Ref, Update, NoEffect, DidCapture} from './ReactSideEffectTags'; @@ -1287,6 +1288,8 @@ function completeWork( return null; } break; + case OffscreenComponent: + return null; } invariant( false, diff --git a/packages/react-reconciler/src/ReactWorkTags.js b/packages/react-reconciler/src/ReactWorkTags.js index c8675c7225..56389ed31f 100644 --- a/packages/react-reconciler/src/ReactWorkTags.js +++ b/packages/react-reconciler/src/ReactWorkTags.js @@ -30,7 +30,8 @@ export type WorkTag = | 19 | 20 | 21 - | 22; + | 22 + | 23; export const FunctionComponent = 0; export const ClassComponent = 1; @@ -55,3 +56,4 @@ export const SuspenseListComponent = 19; export const FundamentalComponent = 20; export const ScopeComponent = 21; export const Block = 22; +export const OffscreenComponent = 23; diff --git a/packages/shared/ReactSymbols.js b/packages/shared/ReactSymbols.js index 672ed8d8aa..bc8122980a 100644 --- a/packages/shared/ReactSymbols.js +++ b/packages/shared/ReactSymbols.js @@ -32,6 +32,7 @@ export let REACT_RESPONDER_TYPE = 0xead6; export let REACT_SCOPE_TYPE = 0xead7; export let REACT_OPAQUE_ID_TYPE = 0xeae0; export let REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; +export let REACT_OFFSCREEN_TYPE = 0xeae2; if (typeof Symbol === 'function' && Symbol.for) { const symbolFor = Symbol.for; @@ -54,6 +55,7 @@ if (typeof Symbol === 'function' && Symbol.for) { REACT_SCOPE_TYPE = symbolFor('react.scope'); REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id'); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode'); + REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen'); } const MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;