mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Move ReactDOMLegacy implementation into RootFB (#28656)
Only the FB entry point has legacy mode now so we can move the remaining code in there. Also enable disableLegacyMode in modern www builds since it doesn't expose those entry points. Now dependent on #28709. --------- Co-authored-by: Josh Story <story@hey.com>
This commit is contained in:
committed by
GitHub
parent
5de8703646
commit
8f55a6aa57
@@ -69,6 +69,7 @@ function mountStrictApp(App) {
|
||||
}
|
||||
|
||||
function mountLegacyApp(App: () => React$Node) {
|
||||
// $FlowFixMe[prop-missing]: These are removed in 19.
|
||||
const {render, unmountComponentAtNode} = require('react-dom');
|
||||
|
||||
function LegacyRender() {
|
||||
@@ -77,8 +78,10 @@ function mountLegacyApp(App: () => React$Node) {
|
||||
|
||||
const container = createContainer();
|
||||
|
||||
// $FlowFixMe[not-a-function]: These are removed in 19.
|
||||
render(createElement(LegacyRender), container);
|
||||
|
||||
// $FlowFixMe: These are removed in 19.
|
||||
unmountFunctions.push(() => unmountComponentAtNode(container));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ function mountApp(App: () => React$Node) {
|
||||
|
||||
((document.body: any): HTMLBodyElement).appendChild(container);
|
||||
|
||||
// $FlowFixMe[prop-missing]: These are removed in 19.
|
||||
ReactDOM.render(<App />, container);
|
||||
}
|
||||
function mountTestApp() {
|
||||
|
||||
@@ -20,11 +20,8 @@ Object.assign((Internals: any), {
|
||||
|
||||
export {
|
||||
createPortal,
|
||||
findDOMNode,
|
||||
flushSync,
|
||||
unmountComponentAtNode,
|
||||
unstable_createEventHandle,
|
||||
unstable_renderSubtreeIntoContainer,
|
||||
unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
|
||||
useFormStatus,
|
||||
useFormState,
|
||||
@@ -42,6 +39,9 @@ export {
|
||||
hydrateRoot,
|
||||
render,
|
||||
unstable_batchedUpdates,
|
||||
findDOMNode,
|
||||
unstable_renderSubtreeIntoContainer,
|
||||
unmountComponentAtNode,
|
||||
} from './src/client/ReactDOMRootFB';
|
||||
|
||||
export {Internals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED};
|
||||
|
||||
3
packages/react-dom/index.js
vendored
3
packages/react-dom/index.js
vendored
@@ -15,11 +15,8 @@ export {
|
||||
createRoot,
|
||||
hydrateRoot,
|
||||
flushSync,
|
||||
render,
|
||||
unmountComponentAtNode,
|
||||
unstable_batchedUpdates,
|
||||
unstable_createEventHandle,
|
||||
unstable_renderSubtreeIntoContainer,
|
||||
unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
|
||||
useFormStatus,
|
||||
useFormState,
|
||||
|
||||
@@ -13,10 +13,7 @@ export {
|
||||
createRoot,
|
||||
hydrateRoot,
|
||||
flushSync,
|
||||
render,
|
||||
unmountComponentAtNode,
|
||||
unstable_batchedUpdates,
|
||||
unstable_renderSubtreeIntoContainer,
|
||||
useFormStatus,
|
||||
useFormState,
|
||||
prefetchDNS,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {FindDOMNodeType} from './client/ReactDOMLegacy.js';
|
||||
import type {HostDispatcher} from './shared/ReactDOMTypes';
|
||||
|
||||
type InternalsType = {
|
||||
@@ -16,7 +15,11 @@ type InternalsType = {
|
||||
ReactDOMCurrentDispatcher: {
|
||||
current: HostDispatcher,
|
||||
},
|
||||
findDOMNode: null | FindDOMNodeType,
|
||||
findDOMNode:
|
||||
| null
|
||||
| ((
|
||||
componentOrElement: React$Component<any, any>,
|
||||
) => null | Element | Text),
|
||||
};
|
||||
|
||||
function noop() {}
|
||||
|
||||
@@ -14,7 +14,6 @@ let act;
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactDOMClient;
|
||||
let findDOMNode;
|
||||
|
||||
const clone = function (o) {
|
||||
return JSON.parse(JSON.stringify(o));
|
||||
@@ -95,8 +94,6 @@ describe('ReactComponentLifeCycle', () => {
|
||||
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
findDOMNode =
|
||||
ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.findDOMNode;
|
||||
ReactDOMClient = require('react-dom/client');
|
||||
});
|
||||
|
||||
@@ -376,6 +373,7 @@ describe('ReactComponentLifeCycle', () => {
|
||||
expect(instance.updater.isMounted(instance)).toBe(false);
|
||||
});
|
||||
|
||||
// @gate www && !disableLegacyMode
|
||||
it('warns if legacy findDOMNode is used inside render', async () => {
|
||||
class Component extends React.Component {
|
||||
state = {isMounted: false};
|
||||
@@ -384,7 +382,7 @@ describe('ReactComponentLifeCycle', () => {
|
||||
}
|
||||
render() {
|
||||
if (this.state.isMounted) {
|
||||
expect(findDOMNode(this).tagName).toBe('DIV');
|
||||
expect(ReactDOM.findDOMNode(this).tagName).toBe('DIV');
|
||||
}
|
||||
return <div />;
|
||||
}
|
||||
|
||||
@@ -103,9 +103,9 @@ describe('ReactDeprecationWarnings', () => {
|
||||
});
|
||||
}
|
||||
}
|
||||
expect(() => {
|
||||
ReactNoop.renderLegacySyncRoot(<Component />);
|
||||
}).toErrorDev([
|
||||
|
||||
ReactNoop.render(<Component />);
|
||||
await expect(async () => await waitForAll([])).toErrorDev([
|
||||
'Component "Component" contains the string ref "refComponent". Support for string refs will be removed in a future major release.',
|
||||
]);
|
||||
await waitForAll([]);
|
||||
|
||||
@@ -586,6 +586,7 @@ describe('ReactTestUtils', () => {
|
||||
});
|
||||
|
||||
// @gate !disableDOMTestUtils
|
||||
// @gate !disableLegacyMode
|
||||
it('should call setState callback with no arguments', async () => {
|
||||
let mockArgs;
|
||||
class Component extends React.Component {
|
||||
|
||||
@@ -11,16 +11,15 @@
|
||||
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
const findDOMNode =
|
||||
ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.findDOMNode;
|
||||
const StrictMode = React.StrictMode;
|
||||
|
||||
describe('findDOMNode', () => {
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should return null if passed null', () => {
|
||||
expect(findDOMNode(null)).toBe(null);
|
||||
expect(ReactDOM.findDOMNode(null)).toBe(null);
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should find dom element', () => {
|
||||
class MyNode extends React.Component {
|
||||
render() {
|
||||
@@ -34,13 +33,13 @@ describe('findDOMNode', () => {
|
||||
|
||||
const container = document.createElement('div');
|
||||
const myNode = ReactDOM.render(<MyNode />, container);
|
||||
const myDiv = findDOMNode(myNode);
|
||||
const mySameDiv = findDOMNode(myDiv);
|
||||
const myDiv = ReactDOM.findDOMNode(myNode);
|
||||
const mySameDiv = ReactDOM.findDOMNode(myDiv);
|
||||
expect(myDiv.tagName).toBe('DIV');
|
||||
expect(mySameDiv).toBe(myDiv);
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should find dom element after an update from null', () => {
|
||||
function Bar({flag}) {
|
||||
if (flag) {
|
||||
@@ -57,23 +56,24 @@ describe('findDOMNode', () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
const myNodeA = ReactDOM.render(<MyNode />, container);
|
||||
const a = findDOMNode(myNodeA);
|
||||
const a = ReactDOM.findDOMNode(myNodeA);
|
||||
expect(a).toBe(null);
|
||||
|
||||
const myNodeB = ReactDOM.render(<MyNode flag={true} />, container);
|
||||
expect(myNodeA === myNodeB).toBe(true);
|
||||
|
||||
const b = findDOMNode(myNodeB);
|
||||
const b = ReactDOM.findDOMNode(myNodeB);
|
||||
expect(b.tagName).toBe('SPAN');
|
||||
});
|
||||
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should reject random objects', () => {
|
||||
expect(function () {
|
||||
findDOMNode({foo: 'bar'});
|
||||
ReactDOM.findDOMNode({foo: 'bar'});
|
||||
}).toThrowError('Argument appears to not be a ReactComponent. Keys: foo');
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should reject unmounted objects with render func', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
@@ -85,16 +85,16 @@ describe('findDOMNode', () => {
|
||||
const inst = ReactDOM.render(<Foo />, container);
|
||||
ReactDOM.unmountComponentAtNode(container);
|
||||
|
||||
expect(() => findDOMNode(inst)).toThrowError(
|
||||
expect(() => ReactDOM.findDOMNode(inst)).toThrowError(
|
||||
'Unable to find node on an unmounted component.',
|
||||
);
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should not throw an error when called within a component that is not mounted', () => {
|
||||
class Bar extends React.Component {
|
||||
UNSAFE_componentWillMount() {
|
||||
expect(findDOMNode(this)).toBeNull();
|
||||
expect(ReactDOM.findDOMNode(this)).toBeNull();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -107,7 +107,7 @@ describe('findDOMNode', () => {
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should warn if used to find a host component inside StrictMode', () => {
|
||||
let parent = undefined;
|
||||
let child = undefined;
|
||||
@@ -129,7 +129,7 @@ describe('findDOMNode', () => {
|
||||
);
|
||||
|
||||
let match;
|
||||
expect(() => (match = findDOMNode(parent))).toErrorDev([
|
||||
expect(() => (match = ReactDOM.findDOMNode(parent))).toErrorDev([
|
||||
'Warning: findDOMNode is deprecated in StrictMode. ' +
|
||||
'findDOMNode was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' +
|
||||
'Instead, add a ref directly to the element you want to reference. ' +
|
||||
@@ -141,7 +141,7 @@ describe('findDOMNode', () => {
|
||||
expect(match).toBe(child);
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
// @gate www && !disableLegacyMode
|
||||
it('findDOMNode should warn if passed a component that is inside StrictMode', () => {
|
||||
let parent = undefined;
|
||||
let child = undefined;
|
||||
@@ -162,7 +162,7 @@ describe('findDOMNode', () => {
|
||||
);
|
||||
|
||||
let match;
|
||||
expect(() => (match = findDOMNode(parent))).toErrorDev([
|
||||
expect(() => (match = ReactDOM.findDOMNode(parent))).toErrorDev([
|
||||
'Warning: findDOMNode is deprecated in StrictMode. ' +
|
||||
'findDOMNode was passed an instance of IsInStrictMode which is inside StrictMode. ' +
|
||||
'Instead, add a ref directly to the element you want to reference. ' +
|
||||
37
packages/react-dom/src/client/ReactDOM.js
vendored
37
packages/react-dom/src/client/ReactDOM.js
vendored
@@ -8,22 +8,12 @@
|
||||
*/
|
||||
|
||||
import type {ReactNodeList} from 'shared/ReactTypes';
|
||||
import type {
|
||||
Container,
|
||||
PublicInstance,
|
||||
} from 'react-dom-bindings/src/client/ReactFiberConfigDOM';
|
||||
import type {
|
||||
RootType,
|
||||
HydrateRootOptions,
|
||||
CreateRootOptions,
|
||||
} from './ReactDOMRoot';
|
||||
|
||||
import {
|
||||
findDOMNode,
|
||||
render,
|
||||
unstable_renderSubtreeIntoContainer,
|
||||
unmountComponentAtNode,
|
||||
} from './ReactDOMLegacy';
|
||||
import {
|
||||
createRoot as createRootImpl,
|
||||
hydrateRoot as hydrateRootImpl,
|
||||
@@ -35,6 +25,7 @@ import {
|
||||
flushSync as flushSyncWithoutWarningIfAlreadyRendering,
|
||||
isAlreadyRendering,
|
||||
injectIntoDevTools,
|
||||
findHostInstance,
|
||||
} from 'react-reconciler/src/ReactFiberReconciler';
|
||||
import {runWithPriority} from 'react-reconciler/src/ReactEventPriorities';
|
||||
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
|
||||
@@ -99,20 +90,6 @@ function createPortal(
|
||||
return createPortalImpl(children, container, null, key);
|
||||
}
|
||||
|
||||
function renderSubtreeIntoContainer(
|
||||
parentComponent: React$Component<any, any>,
|
||||
element: React$Element<any>,
|
||||
containerNode: Container,
|
||||
callback: ?Function,
|
||||
): React$Component<any, any> | PublicInstance | null {
|
||||
return unstable_renderSubtreeIntoContainer(
|
||||
parentComponent,
|
||||
element,
|
||||
containerNode,
|
||||
callback,
|
||||
);
|
||||
}
|
||||
|
||||
function createRoot(
|
||||
container: Element | Document | DocumentFragment,
|
||||
options?: CreateRootOptions,
|
||||
@@ -163,6 +140,12 @@ function flushSync<R>(fn: (() => R) | void): R | void {
|
||||
return flushSyncWithoutWarningIfAlreadyRendering(fn);
|
||||
}
|
||||
|
||||
function findDOMNode(
|
||||
componentOrElement: React$Component<any, any>,
|
||||
): null | Element | Text {
|
||||
return findHostInstance(componentOrElement);
|
||||
}
|
||||
|
||||
// Expose findDOMNode on internals
|
||||
Internals.findDOMNode = findDOMNode;
|
||||
|
||||
@@ -178,15 +161,9 @@ export {
|
||||
unstable_batchedUpdates,
|
||||
flushSync,
|
||||
ReactVersion as version,
|
||||
// Disabled behind disableLegacyReactDOMAPIs
|
||||
findDOMNode,
|
||||
render,
|
||||
unmountComponentAtNode,
|
||||
// exposeConcurrentModeAPIs
|
||||
createRoot,
|
||||
hydrateRoot,
|
||||
// Disabled behind disableUnstableRenderSubtreeIntoContainer
|
||||
renderSubtreeIntoContainer as unstable_renderSubtreeIntoContainer,
|
||||
// enableCreateEventHandleAPI
|
||||
createEventHandle as unstable_createEventHandle,
|
||||
// TODO: Remove this once callers migrate to alternatives.
|
||||
|
||||
434
packages/react-dom/src/client/ReactDOMLegacy.js
vendored
434
packages/react-dom/src/client/ReactDOMLegacy.js
vendored
@@ -1,434 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and 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 {
|
||||
Container,
|
||||
PublicInstance,
|
||||
} from 'react-dom-bindings/src/client/ReactFiberConfigDOM';
|
||||
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {ReactNodeList} from 'shared/ReactTypes';
|
||||
|
||||
import {disableLegacyMode} from 'shared/ReactFeatureFlags';
|
||||
import {clearContainer} from 'react-dom-bindings/src/client/ReactFiberConfigDOM';
|
||||
import {
|
||||
getInstanceFromNode,
|
||||
isContainerMarkedAsRoot,
|
||||
markContainerAsRoot,
|
||||
unmarkContainerAsRoot,
|
||||
} from 'react-dom-bindings/src/client/ReactDOMComponentTree';
|
||||
import {listenToAllSupportedEvents} from 'react-dom-bindings/src/events/DOMPluginEventSystem';
|
||||
import {isValidContainerLegacy} from './ReactDOMRoot';
|
||||
import {
|
||||
DOCUMENT_NODE,
|
||||
ELEMENT_NODE,
|
||||
COMMENT_NODE,
|
||||
} from 'react-dom-bindings/src/client/HTMLNodeType';
|
||||
|
||||
import {
|
||||
createContainer,
|
||||
createHydrationContainer,
|
||||
findHostInstanceWithNoPortals,
|
||||
updateContainer,
|
||||
flushSync,
|
||||
getPublicRootInstance,
|
||||
findHostInstance,
|
||||
findHostInstanceWithWarning,
|
||||
defaultOnUncaughtError,
|
||||
defaultOnCaughtError,
|
||||
} from 'react-reconciler/src/ReactFiberReconciler';
|
||||
import {LegacyRoot} from 'react-reconciler/src/ReactRootTags';
|
||||
import getComponentNameFromType from 'shared/getComponentNameFromType';
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
import {has as hasInstance} from 'shared/ReactInstanceMap';
|
||||
|
||||
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
|
||||
|
||||
let topLevelUpdateWarnings;
|
||||
|
||||
if (__DEV__) {
|
||||
topLevelUpdateWarnings = (container: Container) => {
|
||||
if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
|
||||
const hostInstance = findHostInstanceWithNoPortals(
|
||||
container._reactRootContainer.current,
|
||||
);
|
||||
if (hostInstance) {
|
||||
if (hostInstance.parentNode !== container) {
|
||||
console.error(
|
||||
'It looks like the React-rendered content of this ' +
|
||||
'container was removed without using React. This is not ' +
|
||||
'supported and will cause errors. Instead, call ' +
|
||||
'ReactDOM.unmountComponentAtNode to empty a container.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isRootRenderedBySomeReact = !!container._reactRootContainer;
|
||||
const rootEl = getReactRootElementInContainer(container);
|
||||
const hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
|
||||
|
||||
if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
|
||||
console.error(
|
||||
'Replacing React-rendered children with a new root ' +
|
||||
'component. If you intended to update the children of this node, ' +
|
||||
'you should instead have the existing children update their state ' +
|
||||
'and render the new components instead of calling ReactDOM.render.',
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getReactRootElementInContainer(container: any) {
|
||||
if (!container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (container.nodeType === DOCUMENT_NODE) {
|
||||
return container.documentElement;
|
||||
} else {
|
||||
return container.firstChild;
|
||||
}
|
||||
}
|
||||
|
||||
function noopOnRecoverableError() {
|
||||
// This isn't reachable because onRecoverableError isn't called in the
|
||||
// legacy API.
|
||||
}
|
||||
|
||||
function legacyCreateRootFromDOMContainer(
|
||||
container: Container,
|
||||
initialChildren: ReactNodeList,
|
||||
parentComponent: ?React$Component<any, any>,
|
||||
callback: ?Function,
|
||||
isHydrationContainer: boolean,
|
||||
): FiberRoot {
|
||||
if (isHydrationContainer) {
|
||||
if (typeof callback === 'function') {
|
||||
const originalCallback = callback;
|
||||
callback = function () {
|
||||
const instance = getPublicRootInstance(root);
|
||||
originalCallback.call(instance);
|
||||
};
|
||||
}
|
||||
|
||||
const root: FiberRoot = createHydrationContainer(
|
||||
initialChildren,
|
||||
callback,
|
||||
container,
|
||||
LegacyRoot,
|
||||
null, // hydrationCallbacks
|
||||
false, // isStrictMode
|
||||
false, // concurrentUpdatesByDefaultOverride,
|
||||
'', // identifierPrefix
|
||||
defaultOnUncaughtError,
|
||||
defaultOnCaughtError,
|
||||
noopOnRecoverableError,
|
||||
// TODO(luna) Support hydration later
|
||||
null,
|
||||
null,
|
||||
);
|
||||
container._reactRootContainer = root;
|
||||
markContainerAsRoot(root.current, container);
|
||||
|
||||
const rootContainerElement =
|
||||
container.nodeType === COMMENT_NODE ? container.parentNode : container;
|
||||
// $FlowFixMe[incompatible-call]
|
||||
listenToAllSupportedEvents(rootContainerElement);
|
||||
|
||||
flushSync();
|
||||
return root;
|
||||
} else {
|
||||
// First clear any existing content.
|
||||
clearContainer(container);
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
const originalCallback = callback;
|
||||
callback = function () {
|
||||
const instance = getPublicRootInstance(root);
|
||||
originalCallback.call(instance);
|
||||
};
|
||||
}
|
||||
|
||||
const root = createContainer(
|
||||
container,
|
||||
LegacyRoot,
|
||||
null, // hydrationCallbacks
|
||||
false, // isStrictMode
|
||||
false, // concurrentUpdatesByDefaultOverride,
|
||||
'', // identifierPrefix
|
||||
defaultOnUncaughtError,
|
||||
defaultOnCaughtError,
|
||||
noopOnRecoverableError,
|
||||
null, // transitionCallbacks
|
||||
);
|
||||
container._reactRootContainer = root;
|
||||
markContainerAsRoot(root.current, container);
|
||||
|
||||
const rootContainerElement =
|
||||
container.nodeType === COMMENT_NODE ? container.parentNode : container;
|
||||
// $FlowFixMe[incompatible-call]
|
||||
listenToAllSupportedEvents(rootContainerElement);
|
||||
|
||||
// Initial mount should not be batched.
|
||||
flushSync(() => {
|
||||
updateContainer(initialChildren, root, parentComponent, callback);
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
function warnOnInvalidCallback(callback: mixed): void {
|
||||
if (__DEV__) {
|
||||
if (callback !== null && typeof callback !== 'function') {
|
||||
console.error(
|
||||
'Expected the last optional `callback` argument to be a ' +
|
||||
'function. Instead received: %s.',
|
||||
callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function legacyRenderSubtreeIntoContainer(
|
||||
parentComponent: ?React$Component<any, any>,
|
||||
children: ReactNodeList,
|
||||
container: Container,
|
||||
forceHydrate: boolean,
|
||||
callback: ?Function,
|
||||
): React$Component<any, any> | PublicInstance | null {
|
||||
if (__DEV__) {
|
||||
topLevelUpdateWarnings(container);
|
||||
warnOnInvalidCallback(callback === undefined ? null : callback);
|
||||
}
|
||||
|
||||
const maybeRoot = container._reactRootContainer;
|
||||
let root: FiberRoot;
|
||||
if (!maybeRoot) {
|
||||
// Initial mount
|
||||
root = legacyCreateRootFromDOMContainer(
|
||||
container,
|
||||
children,
|
||||
parentComponent,
|
||||
callback,
|
||||
forceHydrate,
|
||||
);
|
||||
} else {
|
||||
root = maybeRoot;
|
||||
if (typeof callback === 'function') {
|
||||
const originalCallback = callback;
|
||||
callback = function () {
|
||||
const instance = getPublicRootInstance(root);
|
||||
originalCallback.call(instance);
|
||||
};
|
||||
}
|
||||
// Update
|
||||
updateContainer(children, root, parentComponent, callback);
|
||||
}
|
||||
return getPublicRootInstance(root);
|
||||
}
|
||||
|
||||
export type FindDOMNodeType = typeof findDOMNode;
|
||||
|
||||
export function findDOMNode(
|
||||
componentOrElement: Element | ?React$Component<any, any>,
|
||||
): null | Element | Text {
|
||||
if (__DEV__) {
|
||||
const owner = (ReactCurrentOwner.current: any);
|
||||
if (owner !== null && owner.stateNode !== null) {
|
||||
const warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
|
||||
if (!warnedAboutRefsInRender) {
|
||||
console.error(
|
||||
'%s is accessing findDOMNode inside its render(). ' +
|
||||
'render() should be a pure function of props and state. It should ' +
|
||||
'never access something that requires stale data from the previous ' +
|
||||
'render, such as refs. Move this logic to componentDidMount and ' +
|
||||
'componentDidUpdate instead.',
|
||||
getComponentNameFromType(owner.type) || 'A component',
|
||||
);
|
||||
}
|
||||
owner.stateNode._warnedAboutRefsInRender = true;
|
||||
}
|
||||
}
|
||||
if (componentOrElement == null) {
|
||||
return null;
|
||||
}
|
||||
if ((componentOrElement: any).nodeType === ELEMENT_NODE) {
|
||||
return (componentOrElement: any);
|
||||
}
|
||||
if (__DEV__) {
|
||||
return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
|
||||
}
|
||||
return findHostInstance(componentOrElement);
|
||||
}
|
||||
|
||||
export function render(
|
||||
element: React$Element<any>,
|
||||
container: Container,
|
||||
callback: ?Function,
|
||||
): React$Component<any, any> | PublicInstance | null {
|
||||
if (disableLegacyMode) {
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'ReactDOM.render was removed in React 19. Use createRoot instead.',
|
||||
);
|
||||
}
|
||||
throw new Error('ReactDOM: Unsupported Legacy Mode API.');
|
||||
}
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'ReactDOM.render has not been supported since React 18. Use createRoot ' +
|
||||
'instead. Until you switch to the new API, your app will behave as ' +
|
||||
"if it's running React 17. Learn " +
|
||||
'more: https://react.dev/link/switch-to-createroot',
|
||||
);
|
||||
}
|
||||
|
||||
if (!isValidContainerLegacy(container)) {
|
||||
throw new Error('Target container is not a DOM element.');
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
const isModernRoot =
|
||||
isContainerMarkedAsRoot(container) &&
|
||||
container._reactRootContainer === undefined;
|
||||
if (isModernRoot) {
|
||||
console.error(
|
||||
'You are calling ReactDOM.render() on a container that was previously ' +
|
||||
'passed to ReactDOMClient.createRoot(). This is not supported. ' +
|
||||
'Did you mean to call root.render(element)?',
|
||||
);
|
||||
}
|
||||
}
|
||||
return legacyRenderSubtreeIntoContainer(
|
||||
null,
|
||||
element,
|
||||
container,
|
||||
false,
|
||||
callback,
|
||||
);
|
||||
}
|
||||
|
||||
export function unstable_renderSubtreeIntoContainer(
|
||||
parentComponent: React$Component<any, any>,
|
||||
element: React$Element<any>,
|
||||
containerNode: Container,
|
||||
callback: ?Function,
|
||||
): React$Component<any, any> | PublicInstance | null {
|
||||
if (disableLegacyMode) {
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'ReactDOM.unstable_renderSubtreeIntoContainer() was removed in React 19. Consider using a portal instead.',
|
||||
);
|
||||
}
|
||||
throw new Error('ReactDOM: Unsupported Legacy Mode API.');
|
||||
}
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'ReactDOM.unstable_renderSubtreeIntoContainer() has not been supported ' +
|
||||
'since React 18. Consider using a portal instead. Until you switch to ' +
|
||||
"the createRoot API, your app will behave as if it's running React " +
|
||||
'17. Learn more: https://react.dev/link/switch-to-createroot',
|
||||
);
|
||||
}
|
||||
|
||||
if (!isValidContainerLegacy(containerNode)) {
|
||||
throw new Error('Target container is not a DOM element.');
|
||||
}
|
||||
|
||||
if (parentComponent == null || !hasInstance(parentComponent)) {
|
||||
throw new Error('parentComponent must be a valid React Component');
|
||||
}
|
||||
|
||||
return legacyRenderSubtreeIntoContainer(
|
||||
parentComponent,
|
||||
element,
|
||||
containerNode,
|
||||
false,
|
||||
callback,
|
||||
);
|
||||
}
|
||||
|
||||
export function unmountComponentAtNode(container: Container): boolean {
|
||||
if (disableLegacyMode) {
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'unmountComponentAtNode was removed in React 19. Use root.unmount() instead.',
|
||||
);
|
||||
}
|
||||
throw new Error('ReactDOM: Unsupported Legacy Mode API.');
|
||||
}
|
||||
if (!isValidContainerLegacy(container)) {
|
||||
throw new Error('Target container is not a DOM element.');
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
const isModernRoot =
|
||||
isContainerMarkedAsRoot(container) &&
|
||||
container._reactRootContainer === undefined;
|
||||
if (isModernRoot) {
|
||||
console.error(
|
||||
'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' +
|
||||
'passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (container._reactRootContainer) {
|
||||
if (__DEV__) {
|
||||
const rootEl = getReactRootElementInContainer(container);
|
||||
const renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
|
||||
if (renderedByDifferentReact) {
|
||||
console.error(
|
||||
"unmountComponentAtNode(): The node you're attempting to unmount " +
|
||||
'was rendered by another copy of React.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Unmount should not be batched.
|
||||
flushSync(() => {
|
||||
legacyRenderSubtreeIntoContainer(null, null, container, false, () => {
|
||||
// $FlowFixMe[incompatible-type] This should probably use `delete container._reactRootContainer`
|
||||
container._reactRootContainer = null;
|
||||
unmarkContainerAsRoot(container);
|
||||
});
|
||||
});
|
||||
// If you call unmountComponentAtNode twice in quick succession, you'll
|
||||
// get `true` twice. That's probably fine?
|
||||
return true;
|
||||
} else {
|
||||
if (__DEV__) {
|
||||
const rootEl = getReactRootElementInContainer(container);
|
||||
const hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
|
||||
|
||||
// Check if the container itself is a React root node.
|
||||
const isContainerReactRoot =
|
||||
container.nodeType === ELEMENT_NODE &&
|
||||
isValidContainerLegacy(container.parentNode) &&
|
||||
// $FlowFixMe[prop-missing]
|
||||
// $FlowFixMe[incompatible-use]
|
||||
!!container.parentNode._reactRootContainer;
|
||||
|
||||
if (hasNonRootReactChild) {
|
||||
console.error(
|
||||
"unmountComponentAtNode(): The node you're attempting to unmount " +
|
||||
'was rendered by React and is not a top-level container. %s',
|
||||
isContainerReactRoot
|
||||
? 'You may have accidentally passed in a React root node instead ' +
|
||||
'of its container.'
|
||||
: 'Instead, have the parent component update its state and ' +
|
||||
'rerender in order to remove this component.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
119
packages/react-dom/src/client/ReactDOMRootFB.js
vendored
119
packages/react-dom/src/client/ReactDOMRootFB.js
vendored
@@ -33,11 +33,13 @@ import {
|
||||
getInstanceFromNode,
|
||||
isContainerMarkedAsRoot,
|
||||
markContainerAsRoot,
|
||||
unmarkContainerAsRoot,
|
||||
} from 'react-dom-bindings/src/client/ReactDOMComponentTree';
|
||||
import {listenToAllSupportedEvents} from 'react-dom-bindings/src/events/DOMPluginEventSystem';
|
||||
import {isValidContainerLegacy} from './ReactDOMRoot';
|
||||
import {
|
||||
DOCUMENT_NODE,
|
||||
ELEMENT_NODE,
|
||||
COMMENT_NODE,
|
||||
} from 'react-dom-bindings/src/client/HTMLNodeType';
|
||||
|
||||
@@ -49,12 +51,17 @@ import {
|
||||
updateContainer,
|
||||
flushSync,
|
||||
getPublicRootInstance,
|
||||
findHostInstance,
|
||||
findHostInstanceWithWarning,
|
||||
defaultOnUncaughtError,
|
||||
defaultOnCaughtError,
|
||||
} from 'react-reconciler/src/ReactFiberReconciler';
|
||||
import {LegacyRoot} from 'react-reconciler/src/ReactRootTags';
|
||||
import getComponentNameFromType from 'shared/getComponentNameFromType';
|
||||
import {has as hasInstance} from 'shared/ReactInstanceMap';
|
||||
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
|
||||
import assign from 'shared/assign';
|
||||
|
||||
// Provided by www
|
||||
@@ -146,6 +153,8 @@ export function hydrateRoot(
|
||||
);
|
||||
}
|
||||
|
||||
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
|
||||
|
||||
let topLevelUpdateWarnings;
|
||||
|
||||
if (__DEV__) {
|
||||
@@ -331,6 +340,38 @@ function legacyRenderSubtreeIntoContainer(
|
||||
return getPublicRootInstance(root);
|
||||
}
|
||||
|
||||
export function findDOMNode(
|
||||
componentOrElement: Element | ?React$Component<any, any>,
|
||||
): null | Element | Text {
|
||||
if (__DEV__) {
|
||||
const owner = (ReactCurrentOwner.current: any);
|
||||
if (owner !== null && owner.stateNode !== null) {
|
||||
const warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
|
||||
if (!warnedAboutRefsInRender) {
|
||||
console.error(
|
||||
'%s is accessing findDOMNode inside its render(). ' +
|
||||
'render() should be a pure function of props and state. It should ' +
|
||||
'never access something that requires stale data from the previous ' +
|
||||
'render, such as refs. Move this logic to componentDidMount and ' +
|
||||
'componentDidUpdate instead.',
|
||||
getComponentNameFromType(owner.type) || 'A component',
|
||||
);
|
||||
}
|
||||
owner.stateNode._warnedAboutRefsInRender = true;
|
||||
}
|
||||
}
|
||||
if (componentOrElement == null) {
|
||||
return null;
|
||||
}
|
||||
if ((componentOrElement: any).nodeType === ELEMENT_NODE) {
|
||||
return (componentOrElement: any);
|
||||
}
|
||||
if (__DEV__) {
|
||||
return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
|
||||
}
|
||||
return findHostInstance(componentOrElement);
|
||||
}
|
||||
|
||||
export function render(
|
||||
element: React$Element<any>,
|
||||
container: Container,
|
||||
@@ -418,4 +459,82 @@ export function unstable_renderSubtreeIntoContainer(
|
||||
);
|
||||
}
|
||||
|
||||
export function unmountComponentAtNode(container: Container): boolean {
|
||||
if (disableLegacyMode) {
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'unmountComponentAtNode was removed in React 19. Use root.unmount() instead.',
|
||||
);
|
||||
}
|
||||
throw new Error('ReactDOM: Unsupported Legacy Mode API.');
|
||||
}
|
||||
if (!isValidContainerLegacy(container)) {
|
||||
throw new Error('Target container is not a DOM element.');
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
const isModernRoot =
|
||||
isContainerMarkedAsRoot(container) &&
|
||||
container._reactRootContainer === undefined;
|
||||
if (isModernRoot) {
|
||||
console.error(
|
||||
'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' +
|
||||
'passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (container._reactRootContainer) {
|
||||
if (__DEV__) {
|
||||
const rootEl = getReactRootElementInContainer(container);
|
||||
const renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
|
||||
if (renderedByDifferentReact) {
|
||||
console.error(
|
||||
"unmountComponentAtNode(): The node you're attempting to unmount " +
|
||||
'was rendered by another copy of React.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Unmount should not be batched.
|
||||
flushSync(() => {
|
||||
legacyRenderSubtreeIntoContainer(null, null, container, false, () => {
|
||||
// $FlowFixMe[incompatible-type] This should probably use `delete container._reactRootContainer`
|
||||
container._reactRootContainer = null;
|
||||
unmarkContainerAsRoot(container);
|
||||
});
|
||||
});
|
||||
// If you call unmountComponentAtNode twice in quick succession, you'll
|
||||
// get `true` twice. That's probably fine?
|
||||
return true;
|
||||
} else {
|
||||
if (__DEV__) {
|
||||
const rootEl = getReactRootElementInContainer(container);
|
||||
const hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
|
||||
|
||||
// Check if the container itself is a React root node.
|
||||
const isContainerReactRoot =
|
||||
container.nodeType === ELEMENT_NODE &&
|
||||
isValidContainerLegacy(container.parentNode) &&
|
||||
// $FlowFixMe[prop-missing]
|
||||
// $FlowFixMe[incompatible-use]
|
||||
!!container.parentNode._reactRootContainer;
|
||||
|
||||
if (hasNonRootReactChild) {
|
||||
console.error(
|
||||
"unmountComponentAtNode(): The node you're attempting to unmount " +
|
||||
'was rendered by React and is not a top-level container. %s',
|
||||
isContainerReactRoot
|
||||
? 'You may have accidentally passed in a React root node instead ' +
|
||||
'of its container.'
|
||||
: 'Instead, have the parent component update its state and ' +
|
||||
'rerender in order to remove this component.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export {batchedUpdates as unstable_batchedUpdates};
|
||||
|
||||
3
packages/react-dom/unstable_testing.js
vendored
3
packages/react-dom/unstable_testing.js
vendored
@@ -10,11 +10,8 @@
|
||||
export {
|
||||
createPortal,
|
||||
flushSync,
|
||||
render,
|
||||
unmountComponentAtNode,
|
||||
unstable_batchedUpdates,
|
||||
unstable_createEventHandle,
|
||||
unstable_renderSubtreeIntoContainer,
|
||||
unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
|
||||
useFormStatus,
|
||||
useFormState,
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
export {
|
||||
createPortal,
|
||||
flushSync,
|
||||
render,
|
||||
unmountComponentAtNode,
|
||||
unstable_batchedUpdates,
|
||||
unstable_renderSubtreeIntoContainer,
|
||||
useFormStatus,
|
||||
useFormState,
|
||||
prefetchDNS,
|
||||
|
||||
@@ -393,7 +393,7 @@ describe('ReactScope', () => {
|
||||
});
|
||||
|
||||
// @gate www
|
||||
it('DO_NOT_USE_queryAllNodes() works as intended', () => {
|
||||
it('DO_NOT_USE_queryAllNodes() works as intended', async () => {
|
||||
const testScopeQuery = (type, props) => true;
|
||||
const TestScope = React.unstable_Scope;
|
||||
const scopeRef = React.createRef();
|
||||
@@ -417,20 +417,25 @@ describe('ReactScope', () => {
|
||||
);
|
||||
}
|
||||
|
||||
const renderer = ReactTestRenderer.create(<Test toggle={true} />, {
|
||||
createNodeMock: element => {
|
||||
return element;
|
||||
},
|
||||
});
|
||||
let renderer;
|
||||
await act(
|
||||
() =>
|
||||
(renderer = ReactTestRenderer.create(<Test toggle={true} />, {
|
||||
createNodeMock: element => {
|
||||
return element;
|
||||
},
|
||||
unstable_isConcurrent: true,
|
||||
})),
|
||||
);
|
||||
let nodes = scopeRef.current.DO_NOT_USE_queryAllNodes(testScopeQuery);
|
||||
expect(nodes).toEqual([divRef.current, spanRef.current, aRef.current]);
|
||||
renderer.update(<Test toggle={false} />);
|
||||
await act(() => renderer.update(<Test toggle={false} />));
|
||||
nodes = scopeRef.current.DO_NOT_USE_queryAllNodes(testScopeQuery);
|
||||
expect(nodes).toEqual([aRef.current, divRef.current, spanRef.current]);
|
||||
});
|
||||
|
||||
// @gate www
|
||||
it('DO_NOT_USE_queryFirstNode() works as intended', () => {
|
||||
it('DO_NOT_USE_queryFirstNode() works as intended', async () => {
|
||||
const testScopeQuery = (type, props) => true;
|
||||
const TestScope = React.unstable_Scope;
|
||||
const scopeRef = React.createRef();
|
||||
@@ -454,20 +459,26 @@ describe('ReactScope', () => {
|
||||
);
|
||||
}
|
||||
|
||||
const renderer = ReactTestRenderer.create(<Test toggle={true} />, {
|
||||
createNodeMock: element => {
|
||||
return element;
|
||||
},
|
||||
});
|
||||
let renderer;
|
||||
await act(
|
||||
() =>
|
||||
(renderer = ReactTestRenderer.create(<Test toggle={true} />, {
|
||||
createNodeMock: element => {
|
||||
return element;
|
||||
},
|
||||
unstable_isConcurrent: true,
|
||||
})),
|
||||
);
|
||||
let node = scopeRef.current.DO_NOT_USE_queryFirstNode(testScopeQuery);
|
||||
expect(node).toEqual(divRef.current);
|
||||
renderer.update(<Test toggle={false} />);
|
||||
await act(() => renderer.update(<Test toggle={false} />));
|
||||
|
||||
node = scopeRef.current.DO_NOT_USE_queryFirstNode(testScopeQuery);
|
||||
expect(node).toEqual(aRef.current);
|
||||
});
|
||||
|
||||
// @gate www
|
||||
it('containsNode() works as intended', () => {
|
||||
it('containsNode() works as intended', async () => {
|
||||
const TestScope = React.unstable_Scope;
|
||||
const scopeRef = React.createRef();
|
||||
const divRef = React.createRef();
|
||||
@@ -500,23 +511,28 @@ describe('ReactScope', () => {
|
||||
);
|
||||
}
|
||||
|
||||
const renderer = ReactTestRenderer.create(<Test toggle={true} />, {
|
||||
createNodeMock: element => {
|
||||
return element;
|
||||
},
|
||||
});
|
||||
let renderer;
|
||||
await act(
|
||||
() =>
|
||||
(renderer = ReactTestRenderer.create(<Test toggle={true} />, {
|
||||
createNodeMock: element => {
|
||||
return element;
|
||||
},
|
||||
unstable_isConcurrent: true,
|
||||
})),
|
||||
);
|
||||
expect(scopeRef.current.containsNode(divRef.current)).toBe(true);
|
||||
expect(scopeRef.current.containsNode(spanRef.current)).toBe(true);
|
||||
expect(scopeRef.current.containsNode(aRef.current)).toBe(true);
|
||||
expect(scopeRef.current.containsNode(outerSpan.current)).toBe(false);
|
||||
expect(scopeRef.current.containsNode(emRef.current)).toBe(false);
|
||||
renderer.update(<Test toggle={false} />);
|
||||
await act(() => renderer.update(<Test toggle={false} />));
|
||||
expect(scopeRef.current.containsNode(divRef.current)).toBe(true);
|
||||
expect(scopeRef.current.containsNode(spanRef.current)).toBe(true);
|
||||
expect(scopeRef.current.containsNode(aRef.current)).toBe(true);
|
||||
expect(scopeRef.current.containsNode(outerSpan.current)).toBe(false);
|
||||
expect(scopeRef.current.containsNode(emRef.current)).toBe(true);
|
||||
renderer.update(<Test toggle={true} />);
|
||||
await act(() => renderer.update(<Test toggle={true} />));
|
||||
expect(scopeRef.current.containsNode(emRef.current)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -378,7 +378,7 @@ describe('ReactSuspense', () => {
|
||||
expect(container.textContent).toEqual('AB');
|
||||
});
|
||||
|
||||
// @gate forceConcurrentByDefaultForTesting
|
||||
// @gate !disableLegacyMode && forceConcurrentByDefaultForTesting
|
||||
it(
|
||||
'interrupts current render when something suspends with a ' +
|
||||
"delay and we've already skipped over a lower priority update in " +
|
||||
|
||||
@@ -10,12 +10,10 @@
|
||||
'use strict';
|
||||
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactDOMClient;
|
||||
let JSXRuntime;
|
||||
let JSXDEVRuntime;
|
||||
let act;
|
||||
let findDOMNode;
|
||||
|
||||
// NOTE: Prefer to call the JSXRuntime directly in these tests so we can be
|
||||
// certain that we are testing the runtime behavior, as opposed to the Babel
|
||||
@@ -27,11 +25,8 @@ describe('ReactJSXRuntime', () => {
|
||||
React = require('react');
|
||||
JSXRuntime = require('react/jsx-runtime');
|
||||
JSXDEVRuntime = require('react/jsx-dev-runtime');
|
||||
ReactDOM = require('react-dom');
|
||||
ReactDOMClient = require('react-dom/client');
|
||||
act = require('internal-test-utils').act;
|
||||
findDOMNode =
|
||||
ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.findDOMNode;
|
||||
});
|
||||
|
||||
it('allows static methods to be called using the type property', () => {
|
||||
@@ -133,9 +128,9 @@ describe('ReactJSXRuntime', () => {
|
||||
|
||||
const outer = container.firstChild;
|
||||
if (__DEV__) {
|
||||
expect(findDOMNode(outer).className).toBe('moo');
|
||||
expect(outer.className).toBe('moo');
|
||||
} else {
|
||||
expect(findDOMNode(outer).className).toBe('quack');
|
||||
expect(outer.className).toBe('quack');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ export const enableReactTestRendererWarning = __NEXT_MAJOR__;
|
||||
// Disables legacy mode
|
||||
// This allows us to land breaking changes to remove legacy mode APIs in experimental builds
|
||||
// before removing them in stable in the next Major
|
||||
export const disableLegacyMode = __NEXT_MAJOR__;
|
||||
export const disableLegacyMode = true;
|
||||
|
||||
export const disableDOMTestUtils = __NEXT_MAJOR__;
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ const __NEXT_MAJOR__ = __EXPERIMENTAL__;
|
||||
export const enableRefAsProp = __NEXT_MAJOR__;
|
||||
export const disableStringRefs = __NEXT_MAJOR__;
|
||||
export const enableBigIntSupport = __NEXT_MAJOR__;
|
||||
export const disableLegacyMode = __NEXT_MAJOR__;
|
||||
export const disableLegacyMode = true;
|
||||
export const disableLegacyContext = __NEXT_MAJOR__;
|
||||
export const disableDOMTestUtils = __NEXT_MAJOR__;
|
||||
export const enableRenderableContext = __NEXT_MAJOR__;
|
||||
|
||||
@@ -113,7 +113,7 @@ export const useModernStrictMode = true;
|
||||
// because JSX is an extremely hot path.
|
||||
export const disableStringRefs = false;
|
||||
|
||||
export const disableLegacyMode = false;
|
||||
export const disableLegacyMode = __EXPERIMENTAL__;
|
||||
|
||||
export const disableDOMTestUtils = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user