Add enableSuspenseServerRenderer feature flag (#13573)
This commit is contained in:
parent
4e744be6ee
commit
34348a45b4
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils');
|
||||
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactDOMServer;
|
||||
let ReactFeatureFlags;
|
||||
|
||||
function initModules() {
|
||||
// Reset warning cache.
|
||||
jest.resetModuleRegistry();
|
||||
|
||||
ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
ReactFeatureFlags.enableSuspense = true;
|
||||
ReactFeatureFlags.enableSuspenseServerRenderer = true;
|
||||
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
ReactDOMServer = require('react-dom/server');
|
||||
|
||||
// Make them available to the helpers.
|
||||
return {
|
||||
ReactDOM,
|
||||
ReactDOMServer,
|
||||
};
|
||||
}
|
||||
|
||||
const {resetModules, serverRender} = ReactDOMServerIntegrationUtils(
|
||||
initModules,
|
||||
);
|
||||
|
||||
describe('ReactDOMServerPlaceholders', () => {
|
||||
beforeEach(() => {
|
||||
resetModules();
|
||||
});
|
||||
|
||||
it('should always render the fallback when a placeholder is encountered', async () => {
|
||||
const Suspended = props => {
|
||||
throw new Promise(() => {});
|
||||
};
|
||||
const e = await serverRender(
|
||||
<React.Placeholder fallback={<div />}>
|
||||
<Suspended />
|
||||
</React.Placeholder>,
|
||||
);
|
||||
|
||||
expect(e.tagName).toBe('DIV');
|
||||
});
|
||||
});
|
|
@ -23,12 +23,17 @@ import warningWithoutStack from 'shared/warningWithoutStack';
|
|||
import checkPropTypes from 'prop-types/checkPropTypes';
|
||||
import describeComponentFrame from 'shared/describeComponentFrame';
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
import {warnAboutDeprecatedLifecycles} from 'shared/ReactFeatureFlags';
|
||||
import {
|
||||
warnAboutDeprecatedLifecycles,
|
||||
enableSuspenseServerRenderer,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
|
||||
import {
|
||||
REACT_FORWARD_REF_TYPE,
|
||||
REACT_FRAGMENT_TYPE,
|
||||
REACT_STRICT_MODE_TYPE,
|
||||
REACT_ASYNC_MODE_TYPE,
|
||||
REACT_PLACEHOLDER_TYPE,
|
||||
REACT_PORTAL_TYPE,
|
||||
REACT_PROFILER_TYPE,
|
||||
REACT_PROVIDER_TYPE,
|
||||
|
@ -911,6 +916,27 @@ class ReactDOMServerRenderer {
|
|||
this.stack.push(frame);
|
||||
return '';
|
||||
}
|
||||
case REACT_PLACEHOLDER_TYPE: {
|
||||
if (enableSuspenseServerRenderer) {
|
||||
const nextChildren = toArray(
|
||||
// Always use the fallback when synchronously rendering to string.
|
||||
((nextChild: any): ReactElement).props.fallback,
|
||||
);
|
||||
const frame: Frame = {
|
||||
type: null,
|
||||
domNamespace: parentNamespace,
|
||||
children: nextChildren,
|
||||
childIndex: 0,
|
||||
context: context,
|
||||
footer: '',
|
||||
};
|
||||
if (__DEV__) {
|
||||
((frame: any): FrameDev).debugElementStack = [];
|
||||
}
|
||||
this.stack.push(frame);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line-no-fallthrough
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -42,6 +42,9 @@ export const enableProfilerTimer = __PROFILE__;
|
|||
// Track which interactions trigger each commit.
|
||||
export const enableSchedulerTracking = __PROFILE__;
|
||||
|
||||
// Only used in www builds.
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
invariant(false, 'Not implemented.');
|
||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = __DEV__;
|
|||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
||||
export const enableProfilerTimer = __PROFILE__;
|
||||
export const enableSchedulerTracking = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
|||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
||||
export const enableProfilerTimer = __PROFILE__;
|
||||
export const enableSchedulerTracking = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
|
|
@ -27,6 +27,7 @@ export const enableUserTimingAPI = __DEV__;
|
|||
export const warnAboutLegacyContextAPI = __DEV__;
|
||||
export const enableProfilerTimer = __PROFILE__;
|
||||
export const enableSchedulerTracking = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutDeprecatedLifecycles = false;
|
|||
export const warnAboutLegacyContextAPI = false;
|
||||
export const enableProfilerTimer = __PROFILE__;
|
||||
export const enableSchedulerTracking = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
|||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
||||
export const enableProfilerTimer = __PROFILE__;
|
||||
export const enableSchedulerTracking = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
|||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
|
||||
export const enableProfilerTimer = false;
|
||||
export const enableSchedulerTracking = false;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
|||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
|
||||
export const enableProfilerTimer = false;
|
||||
export const enableSchedulerTracking = false;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
|
|
@ -16,6 +16,7 @@ export const {
|
|||
debugRenderPhaseSideEffects,
|
||||
debugRenderPhaseSideEffectsForStrictMode,
|
||||
enableGetDerivedStateFromCatch,
|
||||
enableSuspenseServerRenderer,
|
||||
replayFailedUnitOfWorkWithInvokeGuardedCallback,
|
||||
warnAboutDeprecatedLifecycles,
|
||||
} = require('ReactFeatureFlags');
|
||||
|
|
Loading…
Reference in New Issue