mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove Blocks (#20138)
* Remove Blocks * Remove Flight Server Runtime There's no need for this now that the JSResource is part of the bundler protocol. Might need something for Webpack plugin specifically later. * Devtools
This commit is contained in:
+6
-72
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import type {Wakeable} from 'shared/ReactTypes';
|
||||
import type {BlockComponent, BlockRenderFunction} from 'react/src/ReactBlock';
|
||||
import type {LazyComponent} from 'react/src/ReactLazy';
|
||||
|
||||
import type {
|
||||
@@ -25,11 +24,7 @@ import {
|
||||
parseModel,
|
||||
} from './ReactFlightClientHostConfig';
|
||||
|
||||
import {
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
REACT_ELEMENT_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
import {REACT_LAZY_TYPE, REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
|
||||
|
||||
export type JSONValue =
|
||||
| number
|
||||
@@ -229,15 +224,6 @@ export function reportGlobalError(response: Response, error: Error): void {
|
||||
});
|
||||
}
|
||||
|
||||
function readMaybeChunk<T>(maybeChunk: SomeChunk<T> | T): T {
|
||||
if (maybeChunk == null || !(maybeChunk instanceof Chunk)) {
|
||||
// $FlowFixMe
|
||||
return maybeChunk;
|
||||
}
|
||||
const chunk: SomeChunk<T> = (maybeChunk: any);
|
||||
return readChunk(chunk);
|
||||
}
|
||||
|
||||
function createElement(type, key, props): React$Element<any> {
|
||||
const element: any = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
@@ -279,45 +265,6 @@ function createElement(type, key, props): React$Element<any> {
|
||||
return element;
|
||||
}
|
||||
|
||||
type UninitializedBlockPayload<Data> = [
|
||||
mixed,
|
||||
BlockRenderFunction<any, Data> | SomeChunk<BlockRenderFunction<any, Data>>,
|
||||
Data | SomeChunk<Data>,
|
||||
Response,
|
||||
];
|
||||
|
||||
function initializeBlock<Props, Data>(
|
||||
tuple: UninitializedBlockPayload<Data>,
|
||||
): BlockComponent<Props, Data> {
|
||||
// Require module first and then data. The ordering matters.
|
||||
const moduleExport = readMaybeChunk(tuple[1]);
|
||||
|
||||
// The ordering here is important because this call might suspend.
|
||||
// We don't want that to prevent the module graph for being initialized.
|
||||
const data: Data = readMaybeChunk(tuple[2]);
|
||||
|
||||
return {
|
||||
$$typeof: REACT_BLOCK_TYPE,
|
||||
_status: -1,
|
||||
_data: data,
|
||||
_render: moduleExport,
|
||||
};
|
||||
}
|
||||
|
||||
function createLazyBlock<Props, Data>(
|
||||
tuple: UninitializedBlockPayload<Data>,
|
||||
): LazyComponent<BlockComponent<Props, Data>, UninitializedBlockPayload<Data>> {
|
||||
const lazyType: LazyComponent<
|
||||
BlockComponent<Props, Data>,
|
||||
UninitializedBlockPayload<Data>,
|
||||
> = {
|
||||
$$typeof: REACT_LAZY_TYPE,
|
||||
_payload: tuple,
|
||||
_init: initializeBlock,
|
||||
};
|
||||
return lazyType;
|
||||
}
|
||||
|
||||
function createLazyChunkWrapper<T>(
|
||||
chunk: SomeChunk<T>,
|
||||
): LazyComponent<T, SomeChunk<T>> {
|
||||
@@ -354,25 +301,15 @@ export function parseModelString(
|
||||
} else {
|
||||
const id = parseInt(value.substring(1), 16);
|
||||
const chunk = getChunk(response, id);
|
||||
if (parentObject[0] === REACT_BLOCK_TYPE) {
|
||||
// Block types know how to deal with lazy values.
|
||||
return chunk;
|
||||
}
|
||||
// For anything else we must Suspend this block if
|
||||
// we don't yet have the value.
|
||||
return readChunk(chunk);
|
||||
}
|
||||
}
|
||||
case '@': {
|
||||
if (value === '@') {
|
||||
return REACT_BLOCK_TYPE;
|
||||
} else {
|
||||
const id = parseInt(value.substring(1), 16);
|
||||
const chunk = getChunk(response, id);
|
||||
// We create a React.lazy wrapper around any lazy values.
|
||||
// When passed into React, we'll know how to suspend on this.
|
||||
return createLazyChunkWrapper(chunk);
|
||||
}
|
||||
const id = parseInt(value.substring(1), 16);
|
||||
const chunk = getChunk(response, id);
|
||||
// We create a React.lazy wrapper around any lazy values.
|
||||
// When passed into React, we'll know how to suspend on this.
|
||||
return createLazyChunkWrapper(chunk);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
@@ -387,9 +324,6 @@ export function parseModelTuple(
|
||||
// TODO: Consider having React just directly accept these arrays as elements.
|
||||
// Or even change the ReactElement type to be an array.
|
||||
return createElement(tuple[1], tuple[2], tuple[3]);
|
||||
} else if (tuple[0] === REACT_BLOCK_TYPE) {
|
||||
// TODO: Consider having React just directly accept these arrays as blocks.
|
||||
return createLazyBlock((tuple: any));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,10 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
|
||||
let act;
|
||||
let React;
|
||||
let ReactNoop;
|
||||
let ReactNoopFlightServer;
|
||||
let ReactNoopFlightServerRuntime;
|
||||
let ReactNoopFlightClient;
|
||||
let ErrorBoundary;
|
||||
|
||||
@@ -27,7 +24,6 @@ describe('ReactFlight', () => {
|
||||
React = require('react');
|
||||
ReactNoop = require('react-noop-renderer');
|
||||
ReactNoopFlightServer = require('react-noop-renderer/flight-server');
|
||||
ReactNoopFlightServerRuntime = require('react-noop-renderer/flight-server-runtime');
|
||||
ReactNoopFlightClient = require('react-noop-renderer/flight-client');
|
||||
act = ReactNoop.act;
|
||||
|
||||
@@ -60,25 +56,6 @@ describe('ReactFlight', () => {
|
||||
};
|
||||
}
|
||||
|
||||
function block(render, load) {
|
||||
if (load === undefined) {
|
||||
return () => {
|
||||
return ReactNoopFlightServerRuntime.serverBlockNoData(
|
||||
moduleReference(render),
|
||||
);
|
||||
};
|
||||
}
|
||||
return function(...args) {
|
||||
const curriedLoad = () => {
|
||||
return load(...args);
|
||||
};
|
||||
return ReactNoopFlightServerRuntime.serverBlock(
|
||||
moduleReference(render),
|
||||
curriedLoad,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
it('can render a server component', () => {
|
||||
function Bar({text}) {
|
||||
return text.toUpperCase();
|
||||
@@ -138,59 +115,6 @@ describe('ReactFlight', () => {
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Hello, Seb Smith</span>);
|
||||
});
|
||||
|
||||
if (ReactFeatureFlags.enableBlocksAPI) {
|
||||
it('can transfer a Block to the client and render there, without data', () => {
|
||||
function User(props, data) {
|
||||
return (
|
||||
<span>
|
||||
{props.greeting} {typeof data}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
const loadUser = block(User);
|
||||
const model = {
|
||||
User: loadUser('Seb', 'Smith'),
|
||||
};
|
||||
|
||||
const transport = ReactNoopFlightServer.render(model);
|
||||
|
||||
act(() => {
|
||||
const rootModel = ReactNoopFlightClient.read(transport);
|
||||
const UserClient = rootModel.User;
|
||||
ReactNoop.render(<UserClient greeting="Hello" />);
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Hello undefined</span>);
|
||||
});
|
||||
|
||||
it('can transfer a Block to the client and render there, with data', () => {
|
||||
function load(firstName, lastName) {
|
||||
return {name: firstName + ' ' + lastName};
|
||||
}
|
||||
function User(props, data) {
|
||||
return (
|
||||
<span>
|
||||
{props.greeting}, {data.name}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
const loadUser = block(User, load);
|
||||
const model = {
|
||||
User: loadUser('Seb', 'Smith'),
|
||||
};
|
||||
|
||||
const transport = ReactNoopFlightServer.render(model);
|
||||
|
||||
act(() => {
|
||||
const rootModel = ReactNoopFlightClient.read(transport);
|
||||
const UserClient = rootModel.User;
|
||||
ReactNoop.render(<UserClient greeting="Hello" />);
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Hello, Seb Smith</span>);
|
||||
});
|
||||
}
|
||||
|
||||
it('should error if a non-serializable value is passed to a host component', () => {
|
||||
function EventHandlerProp() {
|
||||
return (
|
||||
|
||||
+1
-3
@@ -30,7 +30,6 @@ import {
|
||||
SimpleMemoComponent,
|
||||
ContextProvider,
|
||||
ForwardRef,
|
||||
Block,
|
||||
} from 'react-reconciler/src/ReactWorkTags';
|
||||
|
||||
type CurrentDispatcherRef = typeof ReactSharedInternals.ReactCurrentDispatcher;
|
||||
@@ -667,8 +666,7 @@ export function inspectHooksOfFiber(
|
||||
if (
|
||||
fiber.tag !== FunctionComponent &&
|
||||
fiber.tag !== SimpleMemoComponent &&
|
||||
fiber.tag !== ForwardRef &&
|
||||
fiber.tag !== Block
|
||||
fiber.tag !== ForwardRef
|
||||
) {
|
||||
throw new Error(
|
||||
'Unknown Fiber. Needs to be a function component to inspect hooks.',
|
||||
|
||||
@@ -17,8 +17,6 @@ import type {LazyComponent} from 'react/src/ReactLazy';
|
||||
import type {CurrentDispatcherRef} from './types';
|
||||
|
||||
import {
|
||||
BLOCK_NUMBER,
|
||||
BLOCK_SYMBOL_STRING,
|
||||
FORWARD_REF_NUMBER,
|
||||
FORWARD_REF_SYMBOL_STRING,
|
||||
LAZY_NUMBER,
|
||||
@@ -276,14 +274,6 @@ export function describeUnknownElementTypeFrameInDEV(
|
||||
ownerFn,
|
||||
currentDispatcherRef,
|
||||
);
|
||||
case BLOCK_NUMBER:
|
||||
case BLOCK_SYMBOL_STRING:
|
||||
return describeFunctionComponentFrame(
|
||||
type._render,
|
||||
source,
|
||||
ownerFn,
|
||||
currentDispatcherRef,
|
||||
);
|
||||
case LAZY_NUMBER:
|
||||
case LAZY_SYMBOL_STRING: {
|
||||
const lazyComponent: LazyComponent<any, any> = (type: any);
|
||||
|
||||
@@ -35,7 +35,6 @@ function describeFiber(
|
||||
IndeterminateComponent,
|
||||
SimpleMemoComponent,
|
||||
ForwardRef,
|
||||
Block,
|
||||
ClassComponent,
|
||||
} = workTagMap;
|
||||
|
||||
@@ -70,13 +69,6 @@ function describeFiber(
|
||||
owner,
|
||||
currentDispatcherRef,
|
||||
);
|
||||
case Block:
|
||||
return describeFunctionComponentFrame(
|
||||
workInProgress.type._render,
|
||||
source,
|
||||
owner,
|
||||
currentDispatcherRef,
|
||||
);
|
||||
case ClassComponent:
|
||||
return describeClassComponentFrame(
|
||||
workInProgress.type,
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
// 2. DevTools must support both Symbol and numeric forms of each symbol;
|
||||
// Since e.g. standalone DevTools runs in a separate process, it can't rely on its own ES capabilities.
|
||||
|
||||
export const BLOCK_NUMBER = 0xead9;
|
||||
export const BLOCK_SYMBOL_STRING = 'Symbol(react.block)';
|
||||
|
||||
export const CONCURRENT_MODE_NUMBER = 0xeacf;
|
||||
export const CONCURRENT_MODE_SYMBOL_STRING = 'Symbol(react.concurrent_mode)';
|
||||
|
||||
@@ -61,9 +58,6 @@ export const PROVIDER_SYMBOL_STRING = 'Symbol(react.provider)';
|
||||
export const SCOPE_NUMBER = 0xead7;
|
||||
export const SCOPE_SYMBOL_STRING = 'Symbol(react.scope)';
|
||||
|
||||
export const SERVER_BLOCK_NUMBER = 0xeada;
|
||||
export const SERVER_BLOCK_SYMBOL_STRING = 'Symbol(react.server.block)';
|
||||
|
||||
export const STRICT_MODE_NUMBER = 0xeacc;
|
||||
export const STRICT_MODE_SYMBOL_STRING = 'Symbol(react.strict_mode)';
|
||||
|
||||
|
||||
+1
-5
@@ -169,7 +169,6 @@ export function getInternalReactConstants(
|
||||
if (gte(version, '17.0.0-alpha')) {
|
||||
// TODO (Offscreen) Update the version number above to reflect the first Offscreen alpha/beta release.
|
||||
ReactTypeOfWork = {
|
||||
Block: 22,
|
||||
ClassComponent: 1,
|
||||
ContextConsumer: 9,
|
||||
ContextProvider: 10,
|
||||
@@ -188,7 +187,7 @@ export function getInternalReactConstants(
|
||||
LazyComponent: 16,
|
||||
MemoComponent: 14,
|
||||
Mode: 8,
|
||||
OffscreenComponent: 23, // Experimental
|
||||
OffscreenComponent: 22, // Experimental
|
||||
Profiler: 12,
|
||||
SimpleMemoComponent: 15,
|
||||
SuspenseComponent: 13,
|
||||
@@ -197,7 +196,6 @@ export function getInternalReactConstants(
|
||||
};
|
||||
} else if (gte(version, '16.6.0-beta.0')) {
|
||||
ReactTypeOfWork = {
|
||||
Block: 22,
|
||||
ClassComponent: 1,
|
||||
ContextConsumer: 9,
|
||||
ContextProvider: 10,
|
||||
@@ -225,7 +223,6 @@ export function getInternalReactConstants(
|
||||
};
|
||||
} else if (gte(version, '16.4.3-alpha')) {
|
||||
ReactTypeOfWork = {
|
||||
Block: -1, // Doesn't exist yet
|
||||
ClassComponent: 2,
|
||||
ContextConsumer: 11,
|
||||
ContextProvider: 12,
|
||||
@@ -253,7 +250,6 @@ export function getInternalReactConstants(
|
||||
};
|
||||
} else {
|
||||
ReactTypeOfWork = {
|
||||
Block: -1, // Doesn't exist yet
|
||||
ClassComponent: 2,
|
||||
ContextConsumer: 12,
|
||||
ContextProvider: 13,
|
||||
|
||||
@@ -26,7 +26,6 @@ export type WorkFlags = number;
|
||||
export type ExpirationTime = number;
|
||||
|
||||
export type WorkTagMap = {|
|
||||
Block: WorkTag,
|
||||
ClassComponent: WorkTag,
|
||||
ContextConsumer: WorkTag,
|
||||
ContextProvider: WorkTag,
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export * from 'react-server/flight-server-runtime';
|
||||
@@ -1,3 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = require('react-server/flight-server-runtime');
|
||||
@@ -29,7 +29,6 @@
|
||||
"flight-client.js",
|
||||
"flight-modules.js",
|
||||
"flight-server.js",
|
||||
"flight-server-runtime.js",
|
||||
"cjs/"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
import type {ReactElement} from 'shared/ReactElementType';
|
||||
import type {ReactPortal} from 'shared/ReactTypes';
|
||||
import type {BlockComponent} from 'react/src/ReactBlock';
|
||||
import type {LazyComponent} from 'react/src/ReactLazy';
|
||||
import type {Fiber} from './ReactInternalTypes';
|
||||
import type {Lanes} from './ReactFiberLane';
|
||||
|
||||
@@ -22,7 +20,6 @@ import {
|
||||
REACT_FRAGMENT_TYPE,
|
||||
REACT_PORTAL_TYPE,
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
import {
|
||||
FunctionComponent,
|
||||
@@ -32,12 +29,10 @@ import {
|
||||
ForwardRef,
|
||||
Fragment,
|
||||
SimpleMemoComponent,
|
||||
Block,
|
||||
} from './ReactWorkTags';
|
||||
import invariant from 'shared/invariant';
|
||||
import {
|
||||
warnAboutStringRefs,
|
||||
enableBlocksAPI,
|
||||
enableLazyElements,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
|
||||
@@ -251,22 +246,6 @@ function warnOnFunctionType(returnFiber: Fiber) {
|
||||
}
|
||||
}
|
||||
|
||||
// We avoid inlining this to avoid potential deopts from using try/catch.
|
||||
/** @noinline */
|
||||
function resolveLazyType<T, P>(
|
||||
lazyComponent: LazyComponent<T, P>,
|
||||
): LazyComponent<T, P> | T {
|
||||
try {
|
||||
// If we can, let's peek at the resulting type.
|
||||
const payload = lazyComponent._payload;
|
||||
const init = lazyComponent._init;
|
||||
return init(payload);
|
||||
} catch (x) {
|
||||
// Leave it in place and let it throw again in the begin phase.
|
||||
return lazyComponent;
|
||||
}
|
||||
}
|
||||
|
||||
// This wrapper function exists because I expect to clone the code in each path
|
||||
// to be able to optimize each path individually by branching early. This needs
|
||||
// a compiler or we can do it manually. Helpers that don't need this branching
|
||||
@@ -412,28 +391,6 @@ function ChildReconciler(shouldTrackSideEffects) {
|
||||
existing._debugOwner = element._owner;
|
||||
}
|
||||
return existing;
|
||||
} else if (enableBlocksAPI && current.tag === Block) {
|
||||
// The new Block might not be initialized yet. We need to initialize
|
||||
// it in case initializing it turns out it would match.
|
||||
let type = element.type;
|
||||
if (type.$$typeof === REACT_LAZY_TYPE) {
|
||||
type = resolveLazyType(type);
|
||||
}
|
||||
if (
|
||||
type.$$typeof === REACT_BLOCK_TYPE &&
|
||||
((type: any): BlockComponent<any, any>)._render ===
|
||||
(current.type: BlockComponent<any, any>)._render
|
||||
) {
|
||||
// Same as above but also update the .type field.
|
||||
const existing = useFiber(current, element.props);
|
||||
existing.return = returnFiber;
|
||||
existing.type = type;
|
||||
if (__DEV__) {
|
||||
existing._debugSource = element._source;
|
||||
existing._debugOwner = element._owner;
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Insert
|
||||
@@ -1151,33 +1108,6 @@ function ChildReconciler(shouldTrackSideEffects) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Block:
|
||||
if (enableBlocksAPI) {
|
||||
let type = element.type;
|
||||
if (type.$$typeof === REACT_LAZY_TYPE) {
|
||||
type = resolveLazyType(type);
|
||||
}
|
||||
if (type.$$typeof === REACT_BLOCK_TYPE) {
|
||||
// The new Block might not be initialized yet. We need to initialize
|
||||
// it in case initializing it turns out it would match.
|
||||
if (
|
||||
((type: any): BlockComponent<any, any>)._render ===
|
||||
(child.type: BlockComponent<any, any>)._render
|
||||
) {
|
||||
deleteRemainingChildren(returnFiber, child.sibling);
|
||||
const existing = useFiber(child, element.props);
|
||||
existing.type = type;
|
||||
existing.return = returnFiber;
|
||||
if (__DEV__) {
|
||||
existing._debugSource = element._source;
|
||||
existing._debugOwner = element._owner;
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
// We intentionally fallthrough here if enableBlocksAPI is not on.
|
||||
// eslint-disable-next-lined no-fallthrough
|
||||
default: {
|
||||
if (
|
||||
child.elementType === element.type ||
|
||||
@@ -1380,7 +1310,6 @@ function ChildReconciler(shouldTrackSideEffects) {
|
||||
// Intentionally fall through to the next case, which handles both
|
||||
// functions and classes
|
||||
// eslint-disable-next-lined no-fallthrough
|
||||
case Block:
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent: {
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
import type {ReactElement} from 'shared/ReactElementType';
|
||||
import type {ReactPortal} from 'shared/ReactTypes';
|
||||
import type {BlockComponent} from 'react/src/ReactBlock';
|
||||
import type {LazyComponent} from 'react/src/ReactLazy';
|
||||
import type {Fiber} from './ReactInternalTypes';
|
||||
import type {Lanes} from './ReactFiberLane';
|
||||
|
||||
@@ -22,7 +20,6 @@ import {
|
||||
REACT_FRAGMENT_TYPE,
|
||||
REACT_PORTAL_TYPE,
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
import {
|
||||
FunctionComponent,
|
||||
@@ -32,12 +29,10 @@ import {
|
||||
ForwardRef,
|
||||
Fragment,
|
||||
SimpleMemoComponent,
|
||||
Block,
|
||||
} from './ReactWorkTags';
|
||||
import invariant from 'shared/invariant';
|
||||
import {
|
||||
warnAboutStringRefs,
|
||||
enableBlocksAPI,
|
||||
enableLazyElements,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
|
||||
@@ -251,22 +246,6 @@ function warnOnFunctionType(returnFiber: Fiber) {
|
||||
}
|
||||
}
|
||||
|
||||
// We avoid inlining this to avoid potential deopts from using try/catch.
|
||||
/** @noinline */
|
||||
function resolveLazyType<T, P>(
|
||||
lazyComponent: LazyComponent<T, P>,
|
||||
): LazyComponent<T, P> | T {
|
||||
try {
|
||||
// If we can, let's peek at the resulting type.
|
||||
const payload = lazyComponent._payload;
|
||||
const init = lazyComponent._init;
|
||||
return init(payload);
|
||||
} catch (x) {
|
||||
// Leave it in place and let it throw again in the begin phase.
|
||||
return lazyComponent;
|
||||
}
|
||||
}
|
||||
|
||||
// This wrapper function exists because I expect to clone the code in each path
|
||||
// to be able to optimize each path individually by branching early. This needs
|
||||
// a compiler or we can do it manually. Helpers that don't need this branching
|
||||
@@ -419,28 +398,6 @@ function ChildReconciler(shouldTrackSideEffects) {
|
||||
existing._debugOwner = element._owner;
|
||||
}
|
||||
return existing;
|
||||
} else if (enableBlocksAPI && current.tag === Block) {
|
||||
// The new Block might not be initialized yet. We need to initialize
|
||||
// it in case initializing it turns out it would match.
|
||||
let type = element.type;
|
||||
if (type.$$typeof === REACT_LAZY_TYPE) {
|
||||
type = resolveLazyType(type);
|
||||
}
|
||||
if (
|
||||
type.$$typeof === REACT_BLOCK_TYPE &&
|
||||
((type: any): BlockComponent<any, any>)._render ===
|
||||
(current.type: BlockComponent<any, any>)._render
|
||||
) {
|
||||
// Same as above but also update the .type field.
|
||||
const existing = useFiber(current, element.props);
|
||||
existing.return = returnFiber;
|
||||
existing.type = type;
|
||||
if (__DEV__) {
|
||||
existing._debugSource = element._source;
|
||||
existing._debugOwner = element._owner;
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Insert
|
||||
@@ -1158,33 +1115,6 @@ function ChildReconciler(shouldTrackSideEffects) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Block:
|
||||
if (enableBlocksAPI) {
|
||||
let type = element.type;
|
||||
if (type.$$typeof === REACT_LAZY_TYPE) {
|
||||
type = resolveLazyType(type);
|
||||
}
|
||||
if (type.$$typeof === REACT_BLOCK_TYPE) {
|
||||
// The new Block might not be initialized yet. We need to initialize
|
||||
// it in case initializing it turns out it would match.
|
||||
if (
|
||||
((type: any): BlockComponent<any, any>)._render ===
|
||||
(child.type: BlockComponent<any, any>)._render
|
||||
) {
|
||||
deleteRemainingChildren(returnFiber, child.sibling);
|
||||
const existing = useFiber(child, element.props);
|
||||
existing.type = type;
|
||||
existing.return = returnFiber;
|
||||
if (__DEV__) {
|
||||
existing._debugSource = element._source;
|
||||
existing._debugOwner = element._owner;
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
// We intentionally fallthrough here if enableBlocksAPI is not on.
|
||||
// eslint-disable-next-lined no-fallthrough
|
||||
default: {
|
||||
if (
|
||||
child.elementType === element.type ||
|
||||
@@ -1387,7 +1317,6 @@ function ChildReconciler(shouldTrackSideEffects) {
|
||||
// Intentionally fall through to the next case, which handles both
|
||||
// functions and classes
|
||||
// eslint-disable-next-lined no-fallthrough
|
||||
case Block:
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent: {
|
||||
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
enableProfilerTimer,
|
||||
enableFundamentalAPI,
|
||||
enableScopeAPI,
|
||||
enableBlocksAPI,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
|
||||
import {ConcurrentRoot, BlockingRoot} from './ReactRootTags';
|
||||
@@ -53,7 +52,6 @@ import {
|
||||
LazyComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -88,7 +86,6 @@ import {
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_FUNDAMENTAL_TYPE,
|
||||
REACT_SCOPE_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
REACT_OFFSCREEN_TYPE,
|
||||
REACT_LEGACY_HIDDEN_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
@@ -239,11 +236,6 @@ export function resolveLazyComponentTag(Component: Function): WorkTag {
|
||||
if ($$typeof === REACT_MEMO_TYPE) {
|
||||
return MemoComponent;
|
||||
}
|
||||
if (enableBlocksAPI) {
|
||||
if ($$typeof === REACT_BLOCK_TYPE) {
|
||||
return Block;
|
||||
}
|
||||
}
|
||||
}
|
||||
return IndeterminateComponent;
|
||||
}
|
||||
@@ -516,9 +508,6 @@ export function createFiberFromTypeAndProps(
|
||||
fiberTag = LazyComponent;
|
||||
resolvedType = null;
|
||||
break getTag;
|
||||
case REACT_BLOCK_TYPE:
|
||||
fiberTag = Block;
|
||||
break getTag;
|
||||
case REACT_FUNDAMENTAL_TYPE:
|
||||
if (enableFundamentalAPI) {
|
||||
return createFiberFromFundamental(
|
||||
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
enableProfilerTimer,
|
||||
enableFundamentalAPI,
|
||||
enableScopeAPI,
|
||||
enableBlocksAPI,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {NoFlags, Placement} from './ReactFiberFlags';
|
||||
import {ConcurrentRoot, BlockingRoot} from './ReactRootTags';
|
||||
@@ -53,7 +52,6 @@ import {
|
||||
LazyComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -88,7 +86,6 @@ import {
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_FUNDAMENTAL_TYPE,
|
||||
REACT_SCOPE_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
REACT_OFFSCREEN_TYPE,
|
||||
REACT_LEGACY_HIDDEN_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
@@ -241,11 +238,6 @@ export function resolveLazyComponentTag(Component: Function): WorkTag {
|
||||
if ($$typeof === REACT_MEMO_TYPE) {
|
||||
return MemoComponent;
|
||||
}
|
||||
if (enableBlocksAPI) {
|
||||
if ($$typeof === REACT_BLOCK_TYPE) {
|
||||
return Block;
|
||||
}
|
||||
}
|
||||
}
|
||||
return IndeterminateComponent;
|
||||
}
|
||||
@@ -522,9 +514,6 @@ export function createFiberFromTypeAndProps(
|
||||
fiberTag = LazyComponent;
|
||||
resolvedType = null;
|
||||
break getTag;
|
||||
case REACT_BLOCK_TYPE:
|
||||
fiberTag = Block;
|
||||
break getTag;
|
||||
case REACT_FUNDAMENTAL_TYPE:
|
||||
if (enableFundamentalAPI) {
|
||||
return createFiberFromFundamental(
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import type {ReactProviderType, ReactContext} from 'shared/ReactTypes';
|
||||
import type {BlockComponent} from 'react/src/ReactBlock';
|
||||
import type {LazyComponent as LazyComponentType} from 'react/src/ReactLazy';
|
||||
import type {Fiber} from './ReactInternalTypes';
|
||||
import type {FiberRoot} from './ReactInternalTypes';
|
||||
@@ -49,7 +48,6 @@ import {
|
||||
IncompleteClassComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -76,7 +74,6 @@ import {
|
||||
enableFundamentalAPI,
|
||||
warnAboutDefaultPropsOnFunctionComponents,
|
||||
enableScopeAPI,
|
||||
enableBlocksAPI,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import invariant from 'shared/invariant';
|
||||
import shallowEqual from 'shared/shallowEqual';
|
||||
@@ -780,75 +777,6 @@ function updateFunctionComponent(
|
||||
return workInProgress.child;
|
||||
}
|
||||
|
||||
function updateBlock<Props, Data>(
|
||||
current: Fiber | null,
|
||||
workInProgress: Fiber,
|
||||
block: BlockComponent<Props, Data>,
|
||||
nextProps: any,
|
||||
renderLanes: Lanes,
|
||||
) {
|
||||
// TODO: current can be non-null here even if the component
|
||||
// hasn't yet mounted. This happens after the first render suspends.
|
||||
// We'll need to figure out if this is fine or can cause issues.
|
||||
|
||||
const render = block._render;
|
||||
const data = block._data;
|
||||
|
||||
// The rest is a fork of updateFunctionComponent
|
||||
let nextChildren;
|
||||
prepareToReadContext(workInProgress, renderLanes);
|
||||
if (__DEV__) {
|
||||
ReactCurrentOwner.current = workInProgress;
|
||||
setIsRendering(true);
|
||||
nextChildren = renderWithHooks(
|
||||
current,
|
||||
workInProgress,
|
||||
render,
|
||||
nextProps,
|
||||
data,
|
||||
renderLanes,
|
||||
);
|
||||
if (
|
||||
debugRenderPhaseSideEffectsForStrictMode &&
|
||||
workInProgress.mode & StrictMode
|
||||
) {
|
||||
disableLogs();
|
||||
try {
|
||||
nextChildren = renderWithHooks(
|
||||
current,
|
||||
workInProgress,
|
||||
render,
|
||||
nextProps,
|
||||
data,
|
||||
renderLanes,
|
||||
);
|
||||
} finally {
|
||||
reenableLogs();
|
||||
}
|
||||
}
|
||||
setIsRendering(false);
|
||||
} else {
|
||||
nextChildren = renderWithHooks(
|
||||
current,
|
||||
workInProgress,
|
||||
render,
|
||||
nextProps,
|
||||
data,
|
||||
renderLanes,
|
||||
);
|
||||
}
|
||||
|
||||
if (current !== null && !didReceiveUpdate) {
|
||||
bailoutHooks(current, workInProgress, renderLanes);
|
||||
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
|
||||
}
|
||||
|
||||
// React DevTools reads this flag.
|
||||
workInProgress.flags |= PerformedWork;
|
||||
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
|
||||
return workInProgress.child;
|
||||
}
|
||||
|
||||
function updateClassComponent(
|
||||
current: Fiber | null,
|
||||
workInProgress: Fiber,
|
||||
@@ -1265,20 +1193,6 @@ function mountLazyComponent(
|
||||
);
|
||||
return child;
|
||||
}
|
||||
case Block: {
|
||||
if (enableBlocksAPI) {
|
||||
// TODO: Resolve for Hot Reloading.
|
||||
child = updateBlock(
|
||||
null,
|
||||
workInProgress,
|
||||
Component,
|
||||
props,
|
||||
renderLanes,
|
||||
);
|
||||
return child;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
let hint = '';
|
||||
if (__DEV__) {
|
||||
@@ -3454,14 +3368,6 @@ function beginWork(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Block: {
|
||||
if (enableBlocksAPI) {
|
||||
const block = workInProgress.type;
|
||||
const props = workInProgress.pendingProps;
|
||||
return updateBlock(current, workInProgress, block, props, renderLanes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OffscreenComponent: {
|
||||
return updateOffscreenComponent(current, workInProgress, renderLanes);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import type {ReactProviderType, ReactContext} from 'shared/ReactTypes';
|
||||
import type {BlockComponent} from 'react/src/ReactBlock';
|
||||
import type {LazyComponent as LazyComponentType} from 'react/src/ReactLazy';
|
||||
import type {Fiber} from './ReactInternalTypes';
|
||||
import type {FiberRoot} from './ReactInternalTypes';
|
||||
@@ -49,7 +48,6 @@ import {
|
||||
IncompleteClassComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -76,7 +74,6 @@ import {
|
||||
enableFundamentalAPI,
|
||||
warnAboutDefaultPropsOnFunctionComponents,
|
||||
enableScopeAPI,
|
||||
enableBlocksAPI,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import invariant from 'shared/invariant';
|
||||
import shallowEqual from 'shared/shallowEqual';
|
||||
@@ -782,75 +779,6 @@ function updateFunctionComponent(
|
||||
return workInProgress.child;
|
||||
}
|
||||
|
||||
function updateBlock<Props, Data>(
|
||||
current: Fiber | null,
|
||||
workInProgress: Fiber,
|
||||
block: BlockComponent<Props, Data>,
|
||||
nextProps: any,
|
||||
renderLanes: Lanes,
|
||||
) {
|
||||
// TODO: current can be non-null here even if the component
|
||||
// hasn't yet mounted. This happens after the first render suspends.
|
||||
// We'll need to figure out if this is fine or can cause issues.
|
||||
|
||||
const render = block._render;
|
||||
const data = block._data;
|
||||
|
||||
// The rest is a fork of updateFunctionComponent
|
||||
let nextChildren;
|
||||
prepareToReadContext(workInProgress, renderLanes);
|
||||
if (__DEV__) {
|
||||
ReactCurrentOwner.current = workInProgress;
|
||||
setIsRendering(true);
|
||||
nextChildren = renderWithHooks(
|
||||
current,
|
||||
workInProgress,
|
||||
render,
|
||||
nextProps,
|
||||
data,
|
||||
renderLanes,
|
||||
);
|
||||
if (
|
||||
debugRenderPhaseSideEffectsForStrictMode &&
|
||||
workInProgress.mode & StrictMode
|
||||
) {
|
||||
disableLogs();
|
||||
try {
|
||||
nextChildren = renderWithHooks(
|
||||
current,
|
||||
workInProgress,
|
||||
render,
|
||||
nextProps,
|
||||
data,
|
||||
renderLanes,
|
||||
);
|
||||
} finally {
|
||||
reenableLogs();
|
||||
}
|
||||
}
|
||||
setIsRendering(false);
|
||||
} else {
|
||||
nextChildren = renderWithHooks(
|
||||
current,
|
||||
workInProgress,
|
||||
render,
|
||||
nextProps,
|
||||
data,
|
||||
renderLanes,
|
||||
);
|
||||
}
|
||||
|
||||
if (current !== null && !didReceiveUpdate) {
|
||||
bailoutHooks(current, workInProgress, renderLanes);
|
||||
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
|
||||
}
|
||||
|
||||
// React DevTools reads this flag.
|
||||
workInProgress.flags |= PerformedWork;
|
||||
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
|
||||
return workInProgress.child;
|
||||
}
|
||||
|
||||
function updateClassComponent(
|
||||
current: Fiber | null,
|
||||
workInProgress: Fiber,
|
||||
@@ -1264,20 +1192,6 @@ function mountLazyComponent(
|
||||
);
|
||||
return child;
|
||||
}
|
||||
case Block: {
|
||||
if (enableBlocksAPI) {
|
||||
// TODO: Resolve for Hot Reloading.
|
||||
child = updateBlock(
|
||||
null,
|
||||
workInProgress,
|
||||
Component,
|
||||
props,
|
||||
renderLanes,
|
||||
);
|
||||
return child;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
let hint = '';
|
||||
if (__DEV__) {
|
||||
@@ -3470,14 +3384,6 @@ function beginWork(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Block: {
|
||||
if (enableBlocksAPI) {
|
||||
const block = workInProgress.type;
|
||||
const props = workInProgress.pendingProps;
|
||||
return updateBlock(current, workInProgress, block, props, renderLanes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OffscreenComponent: {
|
||||
return updateOffscreenComponent(current, workInProgress, renderLanes);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,6 @@ import {
|
||||
SuspenseListComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -540,8 +539,7 @@ function commitBeforeMutationEffectsOnFiber(finishedWork: Fiber) {
|
||||
switch (finishedWork.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
break;
|
||||
}
|
||||
case ClassComponent: {
|
||||
@@ -1061,8 +1059,7 @@ function recursivelyCommitLayoutEffects(
|
||||
switch (tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
enableProfilerCommitHooks &&
|
||||
@@ -1277,8 +1274,7 @@ function commitLayoutEffectsOnFiber(
|
||||
switch (tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
enableProfilerCommitHooks &&
|
||||
@@ -2131,8 +2127,7 @@ function commitUnmount(
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
const updateQueue: FunctionComponentUpdateQueue | null = (current.updateQueue: any);
|
||||
if (updateQueue !== null) {
|
||||
const lastEffect = updateQueue.lastEffect;
|
||||
@@ -2725,8 +2720,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
// Layout effects are destroyed during the mutation phase so that all
|
||||
// destroy functions for all fibers are called before any create functions.
|
||||
// This prevents sibling component effects from interfering with each other,
|
||||
@@ -2793,8 +2787,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
// Layout effects are destroyed during the mutation phase so that all
|
||||
// destroy functions for all fibers are called before any create functions.
|
||||
// This prevents sibling component effects from interfering with each other,
|
||||
@@ -3049,8 +3042,7 @@ function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
|
||||
switch (finishedWork.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
enableProfilerCommitHooks &&
|
||||
@@ -3082,8 +3074,7 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber(
|
||||
switch (current.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
enableProfilerCommitHooks &&
|
||||
@@ -3115,8 +3106,7 @@ function commitPassiveMountOnFiber(
|
||||
switch (finishedWork.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
enableProfilerCommitHooks &&
|
||||
@@ -3147,8 +3137,7 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
|
||||
switch (fiber.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
invokeGuardedCallback(
|
||||
null,
|
||||
commitHookEffectListMount,
|
||||
@@ -3182,8 +3171,7 @@ function invokePassiveEffectMountInDEV(fiber: Fiber): void {
|
||||
switch (fiber.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
invokeGuardedCallback(
|
||||
null,
|
||||
commitHookEffectListMount,
|
||||
@@ -3208,8 +3196,7 @@ function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void {
|
||||
switch (fiber.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
invokeGuardedCallback(
|
||||
null,
|
||||
commitHookEffectListUnmount,
|
||||
@@ -3242,8 +3229,7 @@ function invokePassiveEffectUnmountInDEV(fiber: Fiber): void {
|
||||
switch (fiber.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
invokeGuardedCallback(
|
||||
null,
|
||||
commitHookEffectListUnmount,
|
||||
|
||||
@@ -52,7 +52,6 @@ import {
|
||||
SuspenseListComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -245,8 +244,7 @@ function commitBeforeMutationLifeCycles(
|
||||
switch (finishedWork.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
return;
|
||||
}
|
||||
case ClassComponent: {
|
||||
@@ -484,8 +482,7 @@ function commitLifeCycles(
|
||||
switch (finishedWork.tag) {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
// At this point layout effects have already been destroyed (during mutation phase).
|
||||
// This is done to prevent sibling component effects from interfering with each other,
|
||||
// e.g. a destroy function in one component should never override a ref set
|
||||
@@ -924,8 +921,7 @@ function commitUnmount(
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
const updateQueue: FunctionComponentUpdateQueue | null = (current.updateQueue: any);
|
||||
if (updateQueue !== null) {
|
||||
const lastEffect = updateQueue.lastEffect;
|
||||
@@ -1486,8 +1482,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
// Layout effects are destroyed during the mutation phase so that all
|
||||
// destroy functions for all fibers are called before any create functions.
|
||||
// This prevents sibling component effects from interfering with each other,
|
||||
@@ -1549,8 +1544,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
|
||||
case FunctionComponent:
|
||||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent:
|
||||
case Block: {
|
||||
case SimpleMemoComponent: {
|
||||
// Layout effects are destroyed during the mutation phase so that all
|
||||
// destroy functions for all fibers are called before any create functions.
|
||||
// This prevents sibling component effects from interfering with each other,
|
||||
|
||||
@@ -54,7 +54,6 @@ import {
|
||||
IncompleteClassComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -140,7 +139,6 @@ import {
|
||||
enableSuspenseServerRenderer,
|
||||
enableFundamentalAPI,
|
||||
enableScopeAPI,
|
||||
enableBlocksAPI,
|
||||
enableProfilerTimer,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {
|
||||
@@ -1505,12 +1503,6 @@ function completeWork(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Block:
|
||||
if (enableBlocksAPI) {
|
||||
bubbleProperties(workInProgress);
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case OffscreenComponent:
|
||||
case LegacyHiddenComponent: {
|
||||
popRenderLanes(workInProgress);
|
||||
|
||||
@@ -54,7 +54,6 @@ import {
|
||||
IncompleteClassComponent,
|
||||
FundamentalComponent,
|
||||
ScopeComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
} from './ReactWorkTags';
|
||||
@@ -120,7 +119,6 @@ import {
|
||||
enableSuspenseServerRenderer,
|
||||
enableFundamentalAPI,
|
||||
enableScopeAPI,
|
||||
enableBlocksAPI,
|
||||
enableProfilerTimer,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {
|
||||
@@ -1256,11 +1254,6 @@ function completeWork(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Block:
|
||||
if (enableBlocksAPI) {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case OffscreenComponent:
|
||||
case LegacyHiddenComponent: {
|
||||
popRenderLanes(workInProgress);
|
||||
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
IndeterminateComponent,
|
||||
ForwardRef,
|
||||
SimpleMemoComponent,
|
||||
Block,
|
||||
ClassComponent,
|
||||
} from './ReactWorkTags';
|
||||
import {
|
||||
@@ -49,8 +48,6 @@ function describeFiber(fiber: Fiber): string {
|
||||
return describeFunctionComponentFrame(fiber.type, source, owner);
|
||||
case ForwardRef:
|
||||
return describeFunctionComponentFrame(fiber.type.render, source, owner);
|
||||
case Block:
|
||||
return describeFunctionComponentFrame(fiber.type._render, source, owner);
|
||||
case ClassComponent:
|
||||
return describeClassComponentFrame(fiber.type, source, owner);
|
||||
default:
|
||||
|
||||
@@ -110,7 +110,6 @@ import {
|
||||
ForwardRef,
|
||||
MemoComponent,
|
||||
SimpleMemoComponent,
|
||||
Block,
|
||||
} from './ReactWorkTags';
|
||||
import {LegacyRoot} from './ReactRootTags';
|
||||
import {
|
||||
@@ -2447,8 +2446,7 @@ function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
|
||||
tag !== FunctionComponent &&
|
||||
tag !== ForwardRef &&
|
||||
tag !== MemoComponent &&
|
||||
tag !== SimpleMemoComponent &&
|
||||
tag !== Block
|
||||
tag !== SimpleMemoComponent
|
||||
) {
|
||||
// Only warn for user-defined components, not internal ones like Suspense.
|
||||
return;
|
||||
@@ -2495,8 +2493,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
|
||||
tag !== FunctionComponent &&
|
||||
tag !== ForwardRef &&
|
||||
tag !== MemoComponent &&
|
||||
tag !== SimpleMemoComponent &&
|
||||
tag !== Block
|
||||
tag !== SimpleMemoComponent
|
||||
) {
|
||||
// Only warn for user-defined components, not internal ones like Suspense.
|
||||
return;
|
||||
|
||||
@@ -108,7 +108,6 @@ import {
|
||||
ForwardRef,
|
||||
MemoComponent,
|
||||
SimpleMemoComponent,
|
||||
Block,
|
||||
OffscreenComponent,
|
||||
LegacyHiddenComponent,
|
||||
ScopeComponent,
|
||||
@@ -3006,8 +3005,7 @@ function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
|
||||
tag !== FunctionComponent &&
|
||||
tag !== ForwardRef &&
|
||||
tag !== MemoComponent &&
|
||||
tag !== SimpleMemoComponent &&
|
||||
tag !== Block
|
||||
tag !== SimpleMemoComponent
|
||||
) {
|
||||
// Only warn for user-defined components, not internal ones like Suspense.
|
||||
return;
|
||||
@@ -3054,8 +3052,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
|
||||
tag !== FunctionComponent &&
|
||||
tag !== ForwardRef &&
|
||||
tag !== MemoComponent &&
|
||||
tag !== SimpleMemoComponent &&
|
||||
tag !== Block
|
||||
tag !== SimpleMemoComponent
|
||||
) {
|
||||
// Only warn for user-defined components, not internal ones like Suspense.
|
||||
return;
|
||||
|
||||
+3
-5
@@ -31,8 +31,7 @@ export type WorkTag =
|
||||
| 20
|
||||
| 21
|
||||
| 22
|
||||
| 23
|
||||
| 24;
|
||||
| 23;
|
||||
|
||||
export const FunctionComponent = 0;
|
||||
export const ClassComponent = 1;
|
||||
@@ -56,6 +55,5 @@ export const DehydratedFragment = 18;
|
||||
export const SuspenseListComponent = 19;
|
||||
export const FundamentalComponent = 20;
|
||||
export const ScopeComponent = 21;
|
||||
export const Block = 22;
|
||||
export const OffscreenComponent = 23;
|
||||
export const LegacyHiddenComponent = 24;
|
||||
export const OffscreenComponent = 22;
|
||||
export const LegacyHiddenComponent = 23;
|
||||
|
||||
@@ -1,351 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
let React;
|
||||
let ReactNoop;
|
||||
let useState;
|
||||
let Suspense;
|
||||
let block;
|
||||
let readString;
|
||||
let resolvePromises;
|
||||
let Scheduler;
|
||||
|
||||
describe('ReactBlocks', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
|
||||
Scheduler = require('scheduler');
|
||||
React = require('react');
|
||||
ReactNoop = require('react-noop-renderer');
|
||||
|
||||
block = React.unstable_block;
|
||||
useState = React.useState;
|
||||
Suspense = React.Suspense;
|
||||
const cache = new Map();
|
||||
let unresolved = [];
|
||||
readString = function(text) {
|
||||
let entry = cache.get(text);
|
||||
if (!entry) {
|
||||
entry = {
|
||||
promise: new Promise(resolve => {
|
||||
unresolved.push(() => {
|
||||
entry.resolved = true;
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
resolved: false,
|
||||
};
|
||||
cache.set(text, entry);
|
||||
}
|
||||
if (!entry.resolved) {
|
||||
throw entry.promise;
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
resolvePromises = () => {
|
||||
const res = unresolved;
|
||||
unresolved = [];
|
||||
res.forEach(r => r());
|
||||
};
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('renders a simple component', () => {
|
||||
function User(props, data) {
|
||||
return <div>{typeof data}</div>;
|
||||
}
|
||||
|
||||
function App({Component}) {
|
||||
return (
|
||||
<Suspense fallback={'Loading...'}>
|
||||
<Component name="Name" />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
const loadUser = block(User);
|
||||
|
||||
ReactNoop.act(() => {
|
||||
ReactNoop.render(<App Component={loadUser()} />);
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput(<div>undefined</div>);
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('prints the name of the render function in warnings', () => {
|
||||
function load(firstName) {
|
||||
return {
|
||||
name: firstName,
|
||||
};
|
||||
}
|
||||
|
||||
function User(props, data) {
|
||||
const array = [<span>{data.name}</span>];
|
||||
return <div>{array}</div>;
|
||||
}
|
||||
|
||||
function App({Component}) {
|
||||
return (
|
||||
<Suspense fallback={'Loading...'}>
|
||||
<Component name="Name" />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
const loadUser = block(User, load);
|
||||
|
||||
expect(() => {
|
||||
ReactNoop.act(() => {
|
||||
ReactNoop.render(<App Component={loadUser()} />);
|
||||
});
|
||||
}).toErrorDev(
|
||||
'Warning: Each child in a list should have a unique ' +
|
||||
'"key" prop.\n\nCheck the render method of `User`. See ' +
|
||||
'https://reactjs.org/link/warning-keys for more information.\n' +
|
||||
' in span (at **)\n' +
|
||||
' in User (at **)\n' +
|
||||
' in Suspense (at **)\n' +
|
||||
' in App (at **)',
|
||||
);
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('renders a component with a suspending load', async () => {
|
||||
function load(id) {
|
||||
return {
|
||||
id: id,
|
||||
name: readString('Sebastian'),
|
||||
};
|
||||
}
|
||||
|
||||
function Render(props, data) {
|
||||
return (
|
||||
<span>
|
||||
{props.title}: {data.name}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const loadUser = block(Render, load);
|
||||
|
||||
function App({User}) {
|
||||
return (
|
||||
<Suspense fallback={'Loading...'}>
|
||||
<User title="Name" />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App User={loadUser(123)} />);
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput('Loading...');
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
resolvePromises();
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Name: Sebastian</span>);
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('does not support a lazy wrapper around a chunk', async () => {
|
||||
function load(id) {
|
||||
return {
|
||||
id: id,
|
||||
name: readString('Sebastian'),
|
||||
};
|
||||
}
|
||||
|
||||
function Render(props, data) {
|
||||
return (
|
||||
<span>
|
||||
{props.title}: {data.name}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const loadUser = block(Render, load);
|
||||
|
||||
function App({User}) {
|
||||
return (
|
||||
<Suspense fallback={'Loading...'}>
|
||||
<User title="Name" />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
let resolveLazy;
|
||||
const LazyUser = React.lazy(
|
||||
() =>
|
||||
new Promise(resolve => {
|
||||
resolveLazy = function() {
|
||||
resolve({
|
||||
default: loadUser(123),
|
||||
});
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App User={LazyUser} />);
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput('Loading...');
|
||||
|
||||
// Resolve the component.
|
||||
await resolveLazy();
|
||||
|
||||
expect(Scheduler).toFlushAndThrow(
|
||||
'Element type is invalid. Received a promise that resolves to: [object Object]. ' +
|
||||
'Lazy element type must resolve to a class or function.' +
|
||||
(__DEV__
|
||||
? ' Did you wrap a component in React.lazy() more than once?'
|
||||
: ''),
|
||||
);
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('can receive updated data for the same component', async () => {
|
||||
function load(firstName) {
|
||||
return {
|
||||
name: firstName,
|
||||
};
|
||||
}
|
||||
|
||||
function Render(props, data) {
|
||||
const [initialName] = useState(data.name);
|
||||
return (
|
||||
<>
|
||||
<span>Initial name: {initialName}</span>
|
||||
<span>Latest name: {data.name}</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const loadUser = block(Render, load);
|
||||
|
||||
function App({User}) {
|
||||
return (
|
||||
<Suspense fallback={'Loading...'}>
|
||||
<User title="Name" />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App User={loadUser('Sebastian')} />);
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
<>
|
||||
<span>Initial name: Sebastian</span>
|
||||
<span>Latest name: Sebastian</span>
|
||||
</>,
|
||||
);
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App User={loadUser('Dan')} />);
|
||||
});
|
||||
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
<>
|
||||
<span>Initial name: Sebastian</span>
|
||||
<span>Latest name: Dan</span>
|
||||
</>,
|
||||
);
|
||||
});
|
||||
|
||||
// Regression test.
|
||||
// @gate experimental
|
||||
it('does not render stale data after ping', async () => {
|
||||
function Child() {
|
||||
return <span>Name: {readString('Sebastian')}</span>;
|
||||
}
|
||||
|
||||
const loadParent = block(
|
||||
function Parent(props, data) {
|
||||
return (
|
||||
<Suspense fallback="Loading...">
|
||||
{data.name ? <Child /> : <span>Empty</span>}
|
||||
</Suspense>
|
||||
);
|
||||
},
|
||||
function load(name) {
|
||||
return {name};
|
||||
},
|
||||
);
|
||||
|
||||
function App({Page}) {
|
||||
return <Page />;
|
||||
}
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App Page={loadParent(null)} />);
|
||||
});
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Empty</span>);
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App Page={loadParent('Sebastian')} />);
|
||||
});
|
||||
await ReactNoop.act(async () => {
|
||||
resolvePromises();
|
||||
});
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Name: Sebastian</span>);
|
||||
});
|
||||
|
||||
// Regression test.
|
||||
// @gate experimental
|
||||
it('does not render stale data after ping and setState', async () => {
|
||||
function Child() {
|
||||
return <span>Name: {readString('Sebastian')}</span>;
|
||||
}
|
||||
|
||||
let _setSuspend;
|
||||
const loadParent = block(
|
||||
function Parent(props, data) {
|
||||
const [suspend, setSuspend] = useState(true);
|
||||
_setSuspend = setSuspend;
|
||||
if (!suspend) {
|
||||
return <span>{data.name}</span>;
|
||||
}
|
||||
return (
|
||||
<Suspense fallback="Loading...">
|
||||
{data.name ? <Child /> : <span>Empty</span>}
|
||||
</Suspense>
|
||||
);
|
||||
},
|
||||
function load(name) {
|
||||
return {name};
|
||||
},
|
||||
);
|
||||
|
||||
function App({Page}) {
|
||||
return <Page />;
|
||||
}
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App Page={loadParent(null)} />);
|
||||
});
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Empty</span>);
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
ReactNoop.render(<App Page={loadParent('Sebastian')} />);
|
||||
});
|
||||
await ReactNoop.act(async () => {
|
||||
_setSuspend(false);
|
||||
resolvePromises();
|
||||
});
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span>Sebastian</span>);
|
||||
});
|
||||
});
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export * from './src/ReactFlightServerRuntime';
|
||||
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-server-flight-server-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-server-flight-server-runtime.development.js');
|
||||
}
|
||||
@@ -14,7 +14,6 @@
|
||||
"README.md",
|
||||
"index.js",
|
||||
"flight.js",
|
||||
"flight-server-runtime.js",
|
||||
"cjs/"
|
||||
],
|
||||
"main": "index.js",
|
||||
|
||||
+1
-54
@@ -31,7 +31,6 @@ import {
|
||||
} from './ReactFlightServerConfig';
|
||||
|
||||
import {
|
||||
REACT_BLOCK_TYPE,
|
||||
REACT_ELEMENT_TYPE,
|
||||
REACT_DEBUG_TRACING_MODE_TYPE,
|
||||
REACT_FORWARD_REF_TYPE,
|
||||
@@ -42,7 +41,6 @@ import {
|
||||
REACT_OFFSCREEN_TYPE,
|
||||
REACT_PROFILER_TYPE,
|
||||
REACT_SCOPE_TYPE,
|
||||
REACT_SERVER_BLOCK_TYPE,
|
||||
REACT_STRICT_MODE_TYPE,
|
||||
REACT_SUSPENSE_TYPE,
|
||||
REACT_SUSPENSE_LIST_TYPE,
|
||||
@@ -138,8 +136,6 @@ function attemptResolveElement(element: React$Element<any>): ReactModel {
|
||||
} else if (typeof type === 'string') {
|
||||
// This is a host element. E.g. HTML.
|
||||
return [REACT_ELEMENT_TYPE, type, element.key, element.props];
|
||||
} else if (type[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
return [REACT_ELEMENT_TYPE, type, element.key, element.props];
|
||||
} else if (
|
||||
type === REACT_FRAGMENT_TYPE ||
|
||||
type === REACT_STRICT_MODE_TYPE ||
|
||||
@@ -386,62 +382,13 @@ export function resolveModelToJSON(
|
||||
switch (value) {
|
||||
case REACT_ELEMENT_TYPE:
|
||||
return '$';
|
||||
case REACT_SERVER_BLOCK_TYPE:
|
||||
return '@';
|
||||
case REACT_LAZY_TYPE:
|
||||
case REACT_BLOCK_TYPE:
|
||||
invariant(
|
||||
false,
|
||||
'React Blocks (and Lazy Components) are expected to be replaced by a ' +
|
||||
'compiler on the server. Try configuring your compiler set up and avoid ' +
|
||||
'using React.lazy inside of Blocks.',
|
||||
'React Lazy Components are not yet supported on the server.',
|
||||
);
|
||||
}
|
||||
|
||||
if (parent[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
// We're currently encoding part of a Block. Look up which key.
|
||||
switch (key) {
|
||||
case '1': {
|
||||
// Module reference
|
||||
// Encode as a normal value.
|
||||
break;
|
||||
}
|
||||
case '2': {
|
||||
// Load function
|
||||
const load: () => ReactModel = (value: any);
|
||||
try {
|
||||
// Attempt to resolve the data.
|
||||
return load();
|
||||
} catch (x) {
|
||||
if (
|
||||
typeof x === 'object' &&
|
||||
x !== null &&
|
||||
typeof x.then === 'function'
|
||||
) {
|
||||
// Something suspended, we'll need to create a new segment and resolve it later.
|
||||
request.pendingChunks++;
|
||||
const newSegment = createSegment(request, load);
|
||||
const ping = newSegment.ping;
|
||||
x.then(ping, ping);
|
||||
return serializeByValueID(newSegment.id);
|
||||
} else {
|
||||
// This load failed, encode the error as a separate row and reference that.
|
||||
request.pendingChunks++;
|
||||
const errorId = request.nextChunkId++;
|
||||
emitErrorChunk(request, errorId, x);
|
||||
return serializeByValueID(errorId);
|
||||
}
|
||||
}
|
||||
}
|
||||
default: {
|
||||
invariant(
|
||||
false,
|
||||
'A server block should never encode any other slots. This is a bug in React.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve server components.
|
||||
while (
|
||||
typeof value === 'object' &&
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {BlockRenderFunction} from 'react/src/ReactBlock';
|
||||
|
||||
import type {ModuleReference} from './ReactFlightServerConfig';
|
||||
|
||||
import {REACT_SERVER_BLOCK_TYPE} from 'shared/ReactSymbols';
|
||||
|
||||
export type ServerBlockComponent<Props, Data> =
|
||||
| [
|
||||
Symbol | number,
|
||||
ModuleReference<BlockRenderFunction<Props, Data>>,
|
||||
() => Data,
|
||||
]
|
||||
| [Symbol | number, ModuleReference<BlockRenderFunction<Props, void>>];
|
||||
|
||||
opaque type ServerBlock<Props>: React$AbstractComponent<
|
||||
Props,
|
||||
null,
|
||||
> = React$AbstractComponent<Props, null>;
|
||||
|
||||
export function serverBlock<Props, Data>(
|
||||
moduleReference: ModuleReference<BlockRenderFunction<Props, Data>>,
|
||||
loadData: () => Data,
|
||||
): ServerBlock<Props> {
|
||||
const blockComponent: ServerBlockComponent<Props, Data> = [
|
||||
REACT_SERVER_BLOCK_TYPE,
|
||||
moduleReference,
|
||||
loadData,
|
||||
];
|
||||
|
||||
// $FlowFixMe: Upstream BlockComponent to Flow as a valid Node.
|
||||
return blockComponent;
|
||||
}
|
||||
|
||||
export function serverBlockNoData<Props>(
|
||||
moduleReference: ModuleReference<BlockRenderFunction<Props, void>>,
|
||||
): ServerBlock<Props> {
|
||||
const blockComponent: ServerBlockComponent<Props, void> = [
|
||||
REACT_SERVER_BLOCK_TYPE,
|
||||
moduleReference,
|
||||
];
|
||||
// $FlowFixMe: Upstream BlockComponent to Flow as a valid Node.
|
||||
return blockComponent;
|
||||
}
|
||||
@@ -39,7 +39,6 @@ import {
|
||||
Profiler,
|
||||
MemoComponent,
|
||||
SimpleMemoComponent,
|
||||
Block,
|
||||
IncompleteClassComponent,
|
||||
ScopeComponent,
|
||||
} from 'react-reconciler/src/ReactWorkTags';
|
||||
@@ -195,14 +194,6 @@ function toTree(node: ?Fiber) {
|
||||
instance: null,
|
||||
rendered: childrenToTree(node.child),
|
||||
};
|
||||
case Block:
|
||||
return {
|
||||
nodeType: 'block',
|
||||
type: node.type,
|
||||
props: {...node.memoizedProps},
|
||||
instance: null,
|
||||
rendered: childrenToTree(node.child),
|
||||
};
|
||||
case HostComponent: {
|
||||
return {
|
||||
nodeType: 'host',
|
||||
@@ -240,7 +231,6 @@ const validWrapperTypes = new Set([
|
||||
ForwardRef,
|
||||
MemoComponent,
|
||||
SimpleMemoComponent,
|
||||
Block,
|
||||
// Normally skipped, but used when there's more than one root child.
|
||||
HostRoot,
|
||||
]);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export * from 'react-server/src/ReactFlightServerRuntime';
|
||||
@@ -12,7 +12,6 @@ let React;
|
||||
let ReactDOM;
|
||||
let JSResourceReference;
|
||||
let ReactDOMFlightRelayServer;
|
||||
let ReactDOMFlightRelayServerRuntime;
|
||||
let ReactDOMFlightRelayClient;
|
||||
|
||||
describe('ReactFlightDOMRelay', () => {
|
||||
@@ -23,7 +22,6 @@ describe('ReactFlightDOMRelay', () => {
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
ReactDOMFlightRelayServer = require('react-transport-dom-relay/server');
|
||||
ReactDOMFlightRelayServerRuntime = require('react-transport-dom-relay/server-runtime');
|
||||
ReactDOMFlightRelayClient = require('react-transport-dom-relay');
|
||||
JSResourceReference = require('JSResourceReference');
|
||||
});
|
||||
@@ -50,22 +48,6 @@ describe('ReactFlightDOMRelay', () => {
|
||||
return model;
|
||||
}
|
||||
|
||||
function block(render, load) {
|
||||
const reference = new JSResourceReference(render);
|
||||
if (load === undefined) {
|
||||
return ReactDOMFlightRelayServerRuntime.serverBlock(reference);
|
||||
}
|
||||
return function(...args) {
|
||||
const curriedLoad = () => {
|
||||
return load(...args);
|
||||
};
|
||||
return ReactDOMFlightRelayServerRuntime.serverBlock(
|
||||
reference,
|
||||
curriedLoad,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
it('can render a server component', () => {
|
||||
function Bar({text}) {
|
||||
return text.toUpperCase();
|
||||
@@ -134,38 +116,6 @@ describe('ReactFlightDOMRelay', () => {
|
||||
expect(container.innerHTML).toEqual('<span>Hello, Seb Smith</span>');
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('can transfer a Block to the client and render there', () => {
|
||||
function load(firstName, lastName) {
|
||||
return {name: firstName + ' ' + lastName};
|
||||
}
|
||||
function User(props, data) {
|
||||
return (
|
||||
<span>
|
||||
{props.greeting}, {data.name}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
const loadUser = block(User, load);
|
||||
const model = {
|
||||
User: loadUser('Seb', 'Smith'),
|
||||
};
|
||||
|
||||
const transport = [];
|
||||
ReactDOMFlightRelayServer.render(model, transport);
|
||||
|
||||
const modelClient = readThrough(transport);
|
||||
|
||||
const container = document.createElement('div');
|
||||
const root = ReactDOM.createRoot(container);
|
||||
act(() => {
|
||||
const UserClient = modelClient.User;
|
||||
root.render(<UserClient greeting="Hello" />);
|
||||
});
|
||||
|
||||
expect(container.innerHTML).toEqual('<span>Hello, Seb Smith</span>');
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('can reasonably handle different element types', () => {
|
||||
const {
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-transport-dom-webpack-server-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-transport-dom-webpack-server-runtime.development.js');
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
"server.js",
|
||||
"server.browser.js",
|
||||
"server.node.js",
|
||||
"server-runtime.js",
|
||||
"cjs/",
|
||||
"umd/"
|
||||
],
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export * from 'react-server/src/ReactFlightServerRuntime';
|
||||
@@ -29,7 +29,6 @@ let Stream;
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactTransportDOMServer;
|
||||
let ReactTransportDOMServerRuntime;
|
||||
let ReactTransportDOMClient;
|
||||
|
||||
describe('ReactFlightDOM', () => {
|
||||
@@ -42,7 +41,6 @@ describe('ReactFlightDOM', () => {
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
ReactTransportDOMServer = require('react-transport-dom-webpack/server');
|
||||
ReactTransportDOMServerRuntime = require('react-transport-dom-webpack/server-runtime');
|
||||
ReactTransportDOMClient = require('react-transport-dom-webpack');
|
||||
});
|
||||
|
||||
@@ -78,25 +76,6 @@ describe('ReactFlightDOM', () => {
|
||||
return {$$typeof: MODULE_TAG, name: 'path/' + idx};
|
||||
}
|
||||
|
||||
function block(render, load) {
|
||||
if (load === undefined) {
|
||||
return () => {
|
||||
return ReactTransportDOMServerRuntime.serverBlockNoData(
|
||||
moduleReference(render),
|
||||
);
|
||||
};
|
||||
}
|
||||
return function(...args) {
|
||||
const curriedLoad = () => {
|
||||
return load(...args);
|
||||
};
|
||||
return ReactTransportDOMServerRuntime.serverBlock(
|
||||
moduleReference(render),
|
||||
curriedLoad,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
async function waitForSuspense(fn) {
|
||||
while (true) {
|
||||
try {
|
||||
@@ -273,220 +252,6 @@ describe('ReactFlightDOM', () => {
|
||||
expect(container.innerHTML).toBe('<p>@div</p>');
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('should progressively reveal Blocks', async () => {
|
||||
const {Suspense} = React;
|
||||
|
||||
class ErrorBoundary extends React.Component {
|
||||
state = {hasError: false, error: null};
|
||||
static getDerivedStateFromError(error) {
|
||||
return {
|
||||
hasError: true,
|
||||
error,
|
||||
};
|
||||
}
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return this.props.fallback(this.state.error);
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
// Model
|
||||
function Text({children}) {
|
||||
return children;
|
||||
}
|
||||
function makeDelayedTextBlock() {
|
||||
let error, _resolve, _reject;
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
_resolve = () => {
|
||||
promise = null;
|
||||
resolve();
|
||||
};
|
||||
_reject = e => {
|
||||
error = e;
|
||||
promise = null;
|
||||
reject(e);
|
||||
};
|
||||
});
|
||||
function load() {
|
||||
if (promise) {
|
||||
throw promise;
|
||||
}
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
return 'data';
|
||||
}
|
||||
function DelayedText({children}, data) {
|
||||
if (data !== 'data') {
|
||||
throw new Error('No data');
|
||||
}
|
||||
return <Text>{children}</Text>;
|
||||
}
|
||||
const loadBlock = block(DelayedText, load);
|
||||
return [loadBlock(), _resolve, _reject];
|
||||
}
|
||||
|
||||
function makeDelayedText() {
|
||||
let error, _resolve, _reject;
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
_resolve = () => {
|
||||
promise = null;
|
||||
resolve();
|
||||
};
|
||||
_reject = e => {
|
||||
error = e;
|
||||
promise = null;
|
||||
reject(e);
|
||||
};
|
||||
});
|
||||
function DelayedText({children}, data) {
|
||||
if (promise) {
|
||||
throw promise;
|
||||
}
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
return <Text>{children}</Text>;
|
||||
}
|
||||
return [DelayedText, _resolve, _reject];
|
||||
}
|
||||
|
||||
const [FriendsModel, resolveFriendsModel] = makeDelayedText();
|
||||
const [NameModel, resolveNameModel] = makeDelayedText();
|
||||
const [PostsModel, resolvePostsModel] = makeDelayedTextBlock();
|
||||
const [PhotosModel, resolvePhotosModel] = makeDelayedTextBlock();
|
||||
const [GamesModel, , rejectGamesModel] = makeDelayedTextBlock();
|
||||
function ProfileMore() {
|
||||
return {
|
||||
avatar: <Text>:avatar:</Text>,
|
||||
friends: <FriendsModel>:friends:</FriendsModel>,
|
||||
posts: <PostsModel>:posts:</PostsModel>,
|
||||
games: <GamesModel>:games:</GamesModel>,
|
||||
};
|
||||
}
|
||||
const profileModel = {
|
||||
photos: <PhotosModel>:photos:</PhotosModel>,
|
||||
name: <NameModel>:name:</NameModel>,
|
||||
more: <ProfileMore />,
|
||||
};
|
||||
|
||||
// View
|
||||
function ProfileDetails({response}) {
|
||||
const model = response.readRoot();
|
||||
return (
|
||||
<div>
|
||||
{model.name}
|
||||
{model.more.avatar}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
function ProfileSidebar({response}) {
|
||||
const model = response.readRoot();
|
||||
return (
|
||||
<div>
|
||||
{model.photos}
|
||||
{model.more.friends}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
function ProfilePosts({response}) {
|
||||
return <div>{response.readRoot().more.posts}</div>;
|
||||
}
|
||||
function ProfileGames({response}) {
|
||||
return <div>{response.readRoot().more.games}</div>;
|
||||
}
|
||||
function ProfilePage({response}) {
|
||||
return (
|
||||
<>
|
||||
<Suspense fallback={<p>(loading)</p>}>
|
||||
<ProfileDetails response={response} />
|
||||
<Suspense fallback={<p>(loading sidebar)</p>}>
|
||||
<ProfileSidebar response={response} />
|
||||
</Suspense>
|
||||
<Suspense fallback={<p>(loading posts)</p>}>
|
||||
<ProfilePosts response={response} />
|
||||
</Suspense>
|
||||
<ErrorBoundary fallback={e => <p>{e.message}</p>}>
|
||||
<Suspense fallback={<p>(loading games)</p>}>
|
||||
<ProfileGames response={response} />
|
||||
</Suspense>
|
||||
</ErrorBoundary>
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const {writable, readable} = getTestStream();
|
||||
ReactTransportDOMServer.pipeToNodeWritable(
|
||||
profileModel,
|
||||
writable,
|
||||
webpackMap,
|
||||
);
|
||||
const response = ReactTransportDOMClient.createFromReadableStream(readable);
|
||||
|
||||
const container = document.createElement('div');
|
||||
const root = ReactDOM.unstable_createRoot(container);
|
||||
await act(async () => {
|
||||
root.render(<ProfilePage response={response} />);
|
||||
});
|
||||
expect(container.innerHTML).toBe('<p>(loading)</p>');
|
||||
|
||||
// This isn't enough to show anything.
|
||||
await act(async () => {
|
||||
resolveFriendsModel();
|
||||
});
|
||||
expect(container.innerHTML).toBe('<p>(loading)</p>');
|
||||
|
||||
// We can now show the details. Sidebar and posts are still loading.
|
||||
await act(async () => {
|
||||
resolveNameModel();
|
||||
});
|
||||
// Advance time enough to trigger a nested fallback.
|
||||
jest.advanceTimersByTime(500);
|
||||
expect(container.innerHTML).toBe(
|
||||
'<div>:name::avatar:</div>' +
|
||||
'<p>(loading sidebar)</p>' +
|
||||
'<p>(loading posts)</p>' +
|
||||
'<p>(loading games)</p>',
|
||||
);
|
||||
|
||||
// Let's *fail* loading games.
|
||||
await act(async () => {
|
||||
rejectGamesModel(new Error('Game over'));
|
||||
});
|
||||
expect(container.innerHTML).toBe(
|
||||
'<div>:name::avatar:</div>' +
|
||||
'<p>(loading sidebar)</p>' +
|
||||
'<p>(loading posts)</p>' +
|
||||
'<p>Game over</p>', // TODO: should not have message in prod.
|
||||
);
|
||||
|
||||
// We can now show the sidebar.
|
||||
await act(async () => {
|
||||
resolvePhotosModel();
|
||||
});
|
||||
expect(container.innerHTML).toBe(
|
||||
'<div>:name::avatar:</div>' +
|
||||
'<div>:photos::friends:</div>' +
|
||||
'<p>(loading posts)</p>' +
|
||||
'<p>Game over</p>', // TODO: should not have message in prod.
|
||||
);
|
||||
|
||||
// Show everything.
|
||||
await act(async () => {
|
||||
resolvePostsModel();
|
||||
});
|
||||
expect(container.innerHTML).toBe(
|
||||
'<div>:name::avatar:</div>' +
|
||||
'<div>:photos::friends:</div>' +
|
||||
'<div>:posts:</div>' +
|
||||
'<p>Game over</p>', // TODO: should not have message in prod.
|
||||
);
|
||||
});
|
||||
|
||||
// @gate experimental
|
||||
it('should progressively reveal server components', async () => {
|
||||
const {Suspense} = React;
|
||||
|
||||
@@ -50,9 +50,6 @@ export {
|
||||
startTransition as unstable_startTransition,
|
||||
SuspenseList,
|
||||
SuspenseList as unstable_SuspenseList,
|
||||
// enableBlocksAPI
|
||||
block,
|
||||
block as unstable_block,
|
||||
// enableScopeAPI
|
||||
unstable_Scope,
|
||||
unstable_useOpaqueIdentifier,
|
||||
|
||||
@@ -44,8 +44,6 @@ export {
|
||||
useDeferredValue as unstable_useDeferredValue,
|
||||
startTransition as unstable_startTransition,
|
||||
SuspenseList as unstable_SuspenseList,
|
||||
// enableBlocksAPI
|
||||
block as unstable_block,
|
||||
unstable_useOpaqueIdentifier,
|
||||
// enableDebugTracing
|
||||
unstable_DebugTracingMode,
|
||||
|
||||
@@ -78,8 +78,6 @@ export {
|
||||
useDeferredValue as unstable_useDeferredValue,
|
||||
SuspenseList,
|
||||
SuspenseList as unstable_SuspenseList,
|
||||
block,
|
||||
block as unstable_block,
|
||||
unstable_LegacyHidden,
|
||||
unstable_createFundamental,
|
||||
unstable_Scope,
|
||||
|
||||
@@ -49,9 +49,6 @@ export {
|
||||
startTransition as unstable_startTransition,
|
||||
SuspenseList,
|
||||
SuspenseList as unstable_SuspenseList,
|
||||
// enableBlocksAPI
|
||||
block,
|
||||
block as unstable_block,
|
||||
// enableScopeAPI
|
||||
unstable_Scope,
|
||||
unstable_useOpaqueIdentifier,
|
||||
|
||||
@@ -32,7 +32,6 @@ import {createContext} from './ReactContext';
|
||||
import {lazy} from './ReactLazy';
|
||||
import {forwardRef} from './ReactForwardRef';
|
||||
import {memo} from './ReactMemo';
|
||||
import {block} from './ReactBlock';
|
||||
import {
|
||||
useCallback,
|
||||
useContext,
|
||||
@@ -111,8 +110,6 @@ export {
|
||||
useDeferredValue,
|
||||
REACT_SUSPENSE_LIST_TYPE as SuspenseList,
|
||||
REACT_LEGACY_HIDDEN_TYPE as unstable_LegacyHidden,
|
||||
// enableBlocksAPI
|
||||
block,
|
||||
// enableFundamentalAPI
|
||||
createFundamental as unstable_createFundamental,
|
||||
// enableScopeAPI
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {LazyComponent} from './ReactLazy';
|
||||
|
||||
import {
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
REACT_MEMO_TYPE,
|
||||
REACT_FORWARD_REF_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
|
||||
type BlockLoadFunction<Args: Iterable<any>, Data> = (...args: Args) => Data;
|
||||
export type BlockRenderFunction<Props, Data> = (
|
||||
props: Props,
|
||||
data: Data,
|
||||
) => React$Node;
|
||||
|
||||
type Payload<Props, Args: Iterable<any>, Data> = {
|
||||
load: BlockLoadFunction<Args, Data>,
|
||||
args: Args,
|
||||
render: BlockRenderFunction<Props, Data>,
|
||||
};
|
||||
|
||||
export type BlockComponent<Props, Data> = {
|
||||
$$typeof: Symbol | number,
|
||||
_data: Data,
|
||||
_render: BlockRenderFunction<Props, Data>,
|
||||
};
|
||||
|
||||
opaque type Block<Props>: React$AbstractComponent<
|
||||
Props,
|
||||
null,
|
||||
> = React$AbstractComponent<Props, null>;
|
||||
|
||||
function lazyInitializer<Props, Args: Iterable<any>, Data>(
|
||||
payload: Payload<Props, Args, Data>,
|
||||
): BlockComponent<Props, Data> {
|
||||
return {
|
||||
$$typeof: REACT_BLOCK_TYPE,
|
||||
_data: payload.load.apply(null, payload.args),
|
||||
_render: payload.render,
|
||||
};
|
||||
}
|
||||
|
||||
export function block<Args: Iterable<any>, Props, Data>(
|
||||
render: BlockRenderFunction<Props, Data>,
|
||||
load?: BlockLoadFunction<Args, Data>,
|
||||
): (...args: Args) => Block<Props> {
|
||||
if (__DEV__) {
|
||||
if (load !== undefined && typeof load !== 'function') {
|
||||
console.error(
|
||||
'Blocks require a load function, if provided, but was given %s.',
|
||||
load === null ? 'null' : typeof load,
|
||||
);
|
||||
}
|
||||
if (render != null && render.$$typeof === REACT_MEMO_TYPE) {
|
||||
console.error(
|
||||
'Blocks require a render function but received a `memo` ' +
|
||||
'component. Use `memo` on an inner component instead.',
|
||||
);
|
||||
} else if (render != null && render.$$typeof === REACT_FORWARD_REF_TYPE) {
|
||||
console.error(
|
||||
'Blocks require a render function but received a `forwardRef` ' +
|
||||
'component. Use `forwardRef` on an inner component instead.',
|
||||
);
|
||||
} else if (typeof render !== 'function') {
|
||||
console.error(
|
||||
'Blocks require a render function but was given %s.',
|
||||
render === null ? 'null' : typeof render,
|
||||
);
|
||||
} else if (render.length !== 0 && render.length !== 2) {
|
||||
// Warn if it's not accepting two args.
|
||||
// Do not warn for 0 arguments because it could be due to usage of the 'arguments' object.
|
||||
console.error(
|
||||
'Block render functions accept exactly two parameters: props and data. %s',
|
||||
render.length === 1
|
||||
? 'Did you forget to use the data parameter?'
|
||||
: 'Any additional parameter will be undefined.',
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
render != null &&
|
||||
(render.defaultProps != null || render.propTypes != null)
|
||||
) {
|
||||
console.error(
|
||||
'Block render functions do not support propTypes or defaultProps. ' +
|
||||
'Did you accidentally pass a React component?',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (load === undefined) {
|
||||
return function(): Block<Props> {
|
||||
const blockComponent: BlockComponent<Props, void> = {
|
||||
$$typeof: REACT_BLOCK_TYPE,
|
||||
_data: undefined,
|
||||
// $FlowFixMe: Data must be void in this scenario.
|
||||
_render: render,
|
||||
};
|
||||
|
||||
// $FlowFixMe: Upstream BlockComponent to Flow as a valid Node.
|
||||
return blockComponent;
|
||||
};
|
||||
}
|
||||
|
||||
// Trick to let Flow refine this.
|
||||
const loadFn = load;
|
||||
|
||||
return function(): Block<Props> {
|
||||
const args: Args = arguments;
|
||||
|
||||
const payload: Payload<Props, Args, Data> = {
|
||||
load: loadFn,
|
||||
args: args,
|
||||
render: render,
|
||||
};
|
||||
|
||||
const lazyType: LazyComponent<
|
||||
BlockComponent<Props, Data>,
|
||||
Payload<Props, Args, Data>,
|
||||
> = {
|
||||
$$typeof: REACT_LAZY_TYPE,
|
||||
_payload: payload,
|
||||
_init: lazyInitializer,
|
||||
};
|
||||
|
||||
// $FlowFixMe: Upstream BlockComponent to Flow as a valid Node.
|
||||
return lazyType;
|
||||
};
|
||||
}
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
REACT_SUSPENSE_LIST_TYPE,
|
||||
REACT_FORWARD_REF_TYPE,
|
||||
REACT_MEMO_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
REACT_LAZY_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
|
||||
@@ -301,8 +300,6 @@ export function describeUnknownElementTypeFrameInDEV(
|
||||
case REACT_MEMO_TYPE:
|
||||
// Memo may contain any component type so we recursively resolve it.
|
||||
return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
|
||||
case REACT_BLOCK_TYPE:
|
||||
return describeFunctionComponentFrame(type._render, source, ownerFn);
|
||||
case REACT_LAZY_TYPE: {
|
||||
const lazyComponent: LazyComponent<any, any> = (type: any);
|
||||
const payload = lazyComponent._payload;
|
||||
|
||||
@@ -44,7 +44,6 @@ export const enableSuspenseServerRenderer = __EXPERIMENTAL__;
|
||||
export const enableSelectiveHydration = __EXPERIMENTAL__;
|
||||
|
||||
// Flight experiments
|
||||
export const enableBlocksAPI = __EXPERIMENTAL__;
|
||||
export const enableLazyElements = __EXPERIMENTAL__;
|
||||
|
||||
// Only used in www builds.
|
||||
|
||||
@@ -25,8 +25,6 @@ export let REACT_SUSPENSE_TYPE = 0xead1;
|
||||
export let REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
export let REACT_MEMO_TYPE = 0xead3;
|
||||
export let REACT_LAZY_TYPE = 0xead4;
|
||||
export let REACT_BLOCK_TYPE = 0xead9;
|
||||
export let REACT_SERVER_BLOCK_TYPE = 0xeada;
|
||||
export let REACT_FUNDAMENTAL_TYPE = 0xead5;
|
||||
export let REACT_SCOPE_TYPE = 0xead7;
|
||||
export let REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
@@ -48,8 +46,6 @@ if (typeof Symbol === 'function' && Symbol.for) {
|
||||
REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_BLOCK_TYPE = symbolFor('react.block');
|
||||
REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
|
||||
REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
|
||||
@@ -18,7 +18,6 @@ export const enableProfilerCommitHooks = false;
|
||||
export const enableSchedulerTracing = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
export const enableSelectiveHydration = false;
|
||||
export const enableBlocksAPI = false;
|
||||
export const enableLazyElements = false;
|
||||
export const enableSchedulerDebugging = false;
|
||||
export const debugRenderPhaseSideEffectsForStrictMode = true;
|
||||
|
||||
@@ -20,7 +20,6 @@ export const enableProfilerCommitHooks = false;
|
||||
export const enableSchedulerTracing = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
export const enableSelectiveHydration = false;
|
||||
export const enableBlocksAPI = false;
|
||||
export const enableLazyElements = false;
|
||||
export const disableJavaScriptURLs = false;
|
||||
export const disableInputAttributeSyncing = false;
|
||||
|
||||
@@ -20,7 +20,6 @@ export const enableProfilerCommitHooks = false;
|
||||
export const enableSchedulerTracing = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
export const enableSelectiveHydration = false;
|
||||
export const enableBlocksAPI = false;
|
||||
export const enableLazyElements = false;
|
||||
export const disableJavaScriptURLs = false;
|
||||
export const disableInputAttributeSyncing = false;
|
||||
|
||||
@@ -20,7 +20,6 @@ export const enableProfilerCommitHooks = false;
|
||||
export const enableSchedulerTracing = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
export const enableSelectiveHydration = false;
|
||||
export const enableBlocksAPI = false;
|
||||
export const enableLazyElements = false;
|
||||
export const disableJavaScriptURLs = false;
|
||||
export const disableInputAttributeSyncing = false;
|
||||
|
||||
@@ -20,7 +20,6 @@ export const enableProfilerCommitHooks = false;
|
||||
export const enableSchedulerTracing = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
export const enableSelectiveHydration = false;
|
||||
export const enableBlocksAPI = false;
|
||||
export const enableLazyElements = false;
|
||||
export const enableSchedulerDebugging = false;
|
||||
export const disableJavaScriptURLs = false;
|
||||
|
||||
@@ -20,7 +20,6 @@ export const enableProfilerCommitHooks = false;
|
||||
export const enableSchedulerTracing = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
export const enableSelectiveHydration = false;
|
||||
export const enableBlocksAPI = false;
|
||||
export const enableLazyElements = false;
|
||||
export const disableJavaScriptURLs = false;
|
||||
export const disableInputAttributeSyncing = false;
|
||||
|
||||
@@ -20,7 +20,6 @@ export const enableProfilerCommitHooks = false;
|
||||
export const enableSchedulerTracing = false;
|
||||
export const enableSuspenseServerRenderer = true;
|
||||
export const enableSelectiveHydration = true;
|
||||
export const enableBlocksAPI = true;
|
||||
export const enableLazyElements = false;
|
||||
export const disableJavaScriptURLs = true;
|
||||
export const disableInputAttributeSyncing = false;
|
||||
|
||||
@@ -54,7 +54,6 @@ export const warnAboutDefaultPropsOnFunctionComponents = false;
|
||||
export const enableSuspenseServerRenderer = true;
|
||||
export const enableSelectiveHydration = true;
|
||||
|
||||
export const enableBlocksAPI = true;
|
||||
export const enableLazyElements = true;
|
||||
|
||||
export const disableJavaScriptURLs = true;
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
REACT_SUSPENSE_TYPE,
|
||||
REACT_SUSPENSE_LIST_TYPE,
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
import type {ReactContext, ReactProviderType} from 'shared/ReactTypes';
|
||||
|
||||
@@ -86,8 +85,6 @@ function getComponentName(type: mixed): string | null {
|
||||
return getWrappedName(type, type.render, 'ForwardRef');
|
||||
case REACT_MEMO_TYPE:
|
||||
return getComponentName(type.type);
|
||||
case REACT_BLOCK_TYPE:
|
||||
return getComponentName(type._render);
|
||||
case REACT_LAZY_TYPE: {
|
||||
const lazyComponent: LazyComponent<any, any> = (type: any);
|
||||
const payload = lazyComponent._payload;
|
||||
|
||||
@@ -21,8 +21,6 @@ import {
|
||||
REACT_LAZY_TYPE,
|
||||
REACT_FUNDAMENTAL_TYPE,
|
||||
REACT_SCOPE_TYPE,
|
||||
REACT_BLOCK_TYPE,
|
||||
REACT_SERVER_BLOCK_TYPE,
|
||||
REACT_LEGACY_HIDDEN_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
import {enableScopeAPI} from './ReactFeatureFlags';
|
||||
@@ -64,9 +62,7 @@ export default function isValidElementType(type: mixed) {
|
||||
// we don't know which Flight build this will end up being used
|
||||
// with.
|
||||
type.$$typeof === REACT_MODULE_REFERENCE ||
|
||||
type.getModuleId !== undefined ||
|
||||
type.$$typeof === REACT_BLOCK_TYPE ||
|
||||
type[(0: any)] === REACT_SERVER_BLOCK_TYPE
|
||||
type.getModuleId !== undefined
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@
|
||||
"349": "Expected a work-in-progress root. This is a bug in React. Please file an issue.",
|
||||
"350": "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue.",
|
||||
"351": "Unsupported server component type: %s",
|
||||
"352": "React Blocks (and Lazy Components) are expected to be replaced by a compiler on the server. Try configuring your compiler set up and avoid using React.lazy inside of Blocks.",
|
||||
"352": "React Lazy Components are not yet supported on the server.",
|
||||
"353": "A server block should never encode any other slots. This is a bug in React.",
|
||||
"354": "getInspectorDataForViewAtPoint() is not available in production.",
|
||||
"355": "The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly.",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// certain conditions. They're like GKs.
|
||||
//
|
||||
// Examples:
|
||||
// // @gate enableBlocksAPI
|
||||
// // @gate enableSomeAPI
|
||||
// test('uses an unstable API', () => {/*...*/})
|
||||
//
|
||||
// // @gate __DEV__
|
||||
@@ -18,12 +18,12 @@
|
||||
//
|
||||
// You can also combine flags using multiple gates:
|
||||
//
|
||||
// // @gate enableBlocksAPI
|
||||
// // @gate enableSomeAPI
|
||||
// // @gate __DEV__
|
||||
// test('both conditions must pass', () => {/*...*/})
|
||||
//
|
||||
// Or using logical operators
|
||||
// // @gate enableBlocksAPI && __DEV__
|
||||
// // @gate enableSomeAPI && __DEV__
|
||||
// test('both conditions must pass', () => {/*...*/})
|
||||
//
|
||||
// Negation also works:
|
||||
|
||||
@@ -265,13 +265,6 @@ const bundles = [
|
||||
global: 'ReactTransportDOMServer',
|
||||
externals: ['react', 'react-dom/server'],
|
||||
},
|
||||
{
|
||||
bundleTypes: [NODE_DEV, NODE_PROD],
|
||||
moduleType: RENDERER,
|
||||
entry: 'react-transport-dom-webpack/server-runtime',
|
||||
global: 'ReactTransportDOMServerRuntime',
|
||||
externals: ['react'],
|
||||
},
|
||||
|
||||
/******* React Transport DOM Client Webpack *******/
|
||||
{
|
||||
@@ -304,17 +297,6 @@ const bundles = [
|
||||
'JSResourceReference',
|
||||
],
|
||||
},
|
||||
{
|
||||
bundleTypes: [FB_WWW_DEV, FB_WWW_PROD],
|
||||
moduleType: RENDERER,
|
||||
entry: 'react-transport-dom-relay/server-runtime',
|
||||
global: 'ReactFlightDOMRelayServerRuntime',
|
||||
externals: [
|
||||
'react',
|
||||
'ReactFlightDOMRelayServerIntegration',
|
||||
'JSResourceReference',
|
||||
],
|
||||
},
|
||||
|
||||
/******* React DOM Flight Client Relay *******/
|
||||
{
|
||||
@@ -521,13 +503,6 @@ const bundles = [
|
||||
global: 'ReactFlightServer',
|
||||
externals: ['react'],
|
||||
},
|
||||
{
|
||||
bundleTypes: [NODE_DEV, NODE_PROD],
|
||||
moduleType: RENDERER,
|
||||
entry: 'react-server/flight-server-runtime',
|
||||
global: 'ReactFlightServerRuntime',
|
||||
externals: ['react'],
|
||||
},
|
||||
|
||||
/******* React Flight Client *******/
|
||||
{
|
||||
|
||||
@@ -14,7 +14,6 @@ module.exports = [
|
||||
'react-dom/testing',
|
||||
'react-dom/unstable-fizz.node',
|
||||
'react-transport-dom-webpack/server.node',
|
||||
'react-transport-dom-webpack/server-runtime',
|
||||
'react-transport-dom-webpack',
|
||||
],
|
||||
paths: [
|
||||
@@ -25,7 +24,6 @@ module.exports = [
|
||||
'react-transport-dom-webpack',
|
||||
'react-transport-dom-webpack/server',
|
||||
'react-transport-dom-webpack/server.node',
|
||||
'react-transport-dom-webpack/server-runtime',
|
||||
'react-transport-dom-webpack/src/ReactFlightDOMServerNode.js', // react-transport-dom-webpack/server.browser
|
||||
'react-client/src/ReactFlightClientStream.js', // We can only type check this in streaming configurations.
|
||||
'react-interactions',
|
||||
@@ -40,7 +38,6 @@ module.exports = [
|
||||
'react-dom/testing',
|
||||
'react-dom/unstable-fizz.browser',
|
||||
'react-transport-dom-webpack/server.browser',
|
||||
'react-transport-dom-webpack/server-runtime',
|
||||
'react-transport-dom-webpack',
|
||||
],
|
||||
paths: [
|
||||
@@ -50,7 +47,6 @@ module.exports = [
|
||||
'react-dom/src/server/ReactDOMFizzServerBrowser.js', // react-dom/unstable-fizz.browser
|
||||
'react-transport-dom-webpack',
|
||||
'react-transport-dom-webpack/server.browser',
|
||||
'react-transport-dom-webpack/server-runtime',
|
||||
'react-transport-dom-webpack/src/ReactFlightDOMServerBrowser.js', // react-transport-dom-webpack/server.browser
|
||||
'react-client/src/ReactFlightClientStream.js', // We can only type check this in streaming configurations.
|
||||
],
|
||||
@@ -90,7 +86,6 @@ module.exports = [
|
||||
entryPoints: [
|
||||
'react-transport-dom-relay',
|
||||
'react-transport-dom-relay/server',
|
||||
'react-transport-dom-relay/server-runtime',
|
||||
],
|
||||
paths: ['react-dom', 'react-transport-dom-relay'],
|
||||
isFlowTyped: true,
|
||||
@@ -103,12 +98,10 @@ module.exports = [
|
||||
'react-client/flight',
|
||||
'react-server',
|
||||
'react-server/flight',
|
||||
'react-server/flight-server-runtime',
|
||||
],
|
||||
paths: [
|
||||
'react-client/flight',
|
||||
'react-server/flight',
|
||||
'react-server/flight-server-runtime',
|
||||
'react-client/src/ReactFlightClientStream.js', // We can only type check this in streaming configurations.
|
||||
],
|
||||
isFlowTyped: true,
|
||||
|
||||
Reference in New Issue
Block a user