Files
react/packages/react-dom/src/client/ReactDOM.js
T
Sebastian Markbåge e40f0b2603 Remove checkReact (#21132)
I don't know what this is useful for but I suspect it was only useful at
FB and is not applicable to ES modules at FB nor elsewhere.
2021-03-29 19:35:58 -07:00

255 lines
7.6 KiB
JavaScript

/**
* 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 {ReactNodeList} from 'shared/ReactTypes';
import type {Container} from './ReactDOMHostConfig';
import {
findDOMNode,
render,
hydrate,
unstable_renderSubtreeIntoContainer,
unmountComponentAtNode,
} from './ReactDOMLegacy';
import {createRoot, isValidContainer} from './ReactDOMRoot';
import {createEventHandle} from './ReactDOMEventHandle';
import {
batchedEventUpdates,
batchedUpdates,
discreteUpdates,
flushDiscreteUpdates,
flushSync,
flushControlled,
injectIntoDevTools,
flushPassiveEffects,
IsThisRendererActing,
attemptSynchronousHydration,
attemptDiscreteHydration,
attemptContinuousHydration,
attemptHydrationAtCurrentPriority,
} from 'react-reconciler/src/ReactFiberReconciler';
import {
runWithPriority,
getCurrentUpdatePriority,
} from 'react-reconciler/src/ReactEventPriorities';
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
import {canUseDOM} from 'shared/ExecutionEnvironment';
import ReactVersion from 'shared/ReactVersion';
import invariant from 'shared/invariant';
import {
warnUnstableRenderSubtreeIntoContainer,
enableNewReconciler,
} from 'shared/ReactFeatureFlags';
import {
getInstanceFromNode,
getNodeFromInstance,
getFiberCurrentPropsFromNode,
getClosestInstanceFromNode,
} from './ReactDOMComponentTree';
import {restoreControlledState} from './ReactDOMComponent';
import {
setAttemptSynchronousHydration,
setAttemptDiscreteHydration,
setAttemptContinuousHydration,
setAttemptHydrationAtCurrentPriority,
queueExplicitHydrationTarget,
setGetCurrentUpdatePriority,
setAttemptHydrationAtPriority,
} from '../events/ReactDOMEventReplaying';
import {setBatchingImplementation} from '../events/ReactDOMUpdateBatching';
import {
setRestoreImplementation,
enqueueStateRestore,
restoreStateIfNeeded,
} from '../events/ReactDOMControlledComponent';
setAttemptSynchronousHydration(attemptSynchronousHydration);
setAttemptDiscreteHydration(attemptDiscreteHydration);
setAttemptContinuousHydration(attemptContinuousHydration);
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
setAttemptHydrationAtPriority(runWithPriority);
let didWarnAboutUnstableCreatePortal = false;
let didWarnAboutUnstableRenderSubtreeIntoContainer = false;
if (__DEV__) {
if (
typeof Map !== 'function' ||
// $FlowIssue Flow incorrectly thinks Map has no prototype
Map.prototype == null ||
typeof Map.prototype.forEach !== 'function' ||
typeof Set !== 'function' ||
// $FlowIssue Flow incorrectly thinks Set has no prototype
Set.prototype == null ||
typeof Set.prototype.clear !== 'function' ||
typeof Set.prototype.forEach !== 'function'
) {
console.error(
'React depends on Map and Set built-in types. Make sure that you load a ' +
'polyfill in older browsers. https://reactjs.org/link/react-polyfills',
);
}
}
setRestoreImplementation(restoreControlledState);
setBatchingImplementation(
batchedUpdates,
discreteUpdates,
flushDiscreteUpdates,
batchedEventUpdates,
);
function createPortal(
children: ReactNodeList,
container: Container,
key: ?string = null,
): React$Portal {
invariant(
isValidContainer(container),
'Target container is not a DOM element.',
);
// TODO: pass ReactDOM portal implementation as third argument
// $FlowFixMe The Flow type is opaque but there's no way to actually create it.
return createPortalImpl(children, container, null, key);
}
function scheduleHydration(target: Node) {
if (target) {
queueExplicitHydrationTarget(target);
}
}
function renderSubtreeIntoContainer(
parentComponent: React$Component<any, any>,
element: React$Element<any>,
containerNode: Container,
callback: ?Function,
) {
if (__DEV__) {
if (
warnUnstableRenderSubtreeIntoContainer &&
!didWarnAboutUnstableRenderSubtreeIntoContainer
) {
didWarnAboutUnstableRenderSubtreeIntoContainer = true;
console.warn(
'ReactDOM.unstable_renderSubtreeIntoContainer() is deprecated ' +
'and will be removed in a future major release. Consider using ' +
'React Portals instead.',
);
}
}
return unstable_renderSubtreeIntoContainer(
parentComponent,
element,
containerNode,
callback,
);
}
function unstable_createPortal(
children: ReactNodeList,
container: Container,
key: ?string = null,
) {
if (__DEV__) {
if (!didWarnAboutUnstableCreatePortal) {
didWarnAboutUnstableCreatePortal = true;
console.warn(
'The ReactDOM.unstable_createPortal() alias has been deprecated, ' +
'and will be removed in React 18+. Update your code to use ' +
'ReactDOM.createPortal() instead. It has the exact same API, ' +
'but without the "unstable_" prefix.',
);
}
}
return createPortal(children, container, key);
}
const Internals = {
// Keep in sync with ReactTestUtils.js, and ReactTestUtilsAct.js.
// This is an array for better minification.
Events: [
getInstanceFromNode,
getNodeFromInstance,
getFiberCurrentPropsFromNode,
enqueueStateRestore,
restoreStateIfNeeded,
flushPassiveEffects,
// TODO: This is related to `act`, not events. Move to separate key?
IsThisRendererActing,
],
};
export {
createPortal,
batchedUpdates as unstable_batchedUpdates,
flushSync,
Internals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
ReactVersion as version,
// Disabled behind disableLegacyReactDOMAPIs
findDOMNode,
hydrate,
render,
unmountComponentAtNode,
// exposeConcurrentModeAPIs
createRoot,
flushControlled as unstable_flushControlled,
scheduleHydration as unstable_scheduleHydration,
// Disabled behind disableUnstableRenderSubtreeIntoContainer
renderSubtreeIntoContainer as unstable_renderSubtreeIntoContainer,
// Disabled behind disableUnstableCreatePortal
// Temporary alias since we already shipped React 16 RC with it.
// TODO: remove in React 18.
unstable_createPortal,
// enableCreateEventHandleAPI
createEventHandle as unstable_createEventHandle,
// TODO: Remove this once callers migrate to alternatives.
// This should only be used by React internals.
runWithPriority as unstable_runWithPriority,
};
const foundDevTools = injectIntoDevTools({
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: __DEV__ ? 1 : 0,
version: ReactVersion,
rendererPackageName: 'react-dom',
});
if (__DEV__) {
if (!foundDevTools && canUseDOM && window.top === window.self) {
// If we're in Chrome or Firefox, provide a download link if not installed.
if (
(navigator.userAgent.indexOf('Chrome') > -1 &&
navigator.userAgent.indexOf('Edge') === -1) ||
navigator.userAgent.indexOf('Firefox') > -1
) {
const protocol = window.location.protocol;
// Don't warn in exotic cases like chrome-extension://.
if (/^(https?|file):$/.test(protocol)) {
// eslint-disable-next-line react-internal/no-production-logging
console.info(
'%cDownload the React DevTools ' +
'for a better development experience: ' +
'https://reactjs.org/link/react-devtools' +
(protocol === 'file:'
? '\nYou might need to use a local HTTP server (instead of file://): ' +
'https://reactjs.org/link/react-devtools-faq'
: ''),
'font-weight:bold',
);
}
}
}
}
export const unstable_isNewReconciler = enableNewReconciler;