mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Refactor React Server entrypoint to not depend on the client one (#27940)
This refactors the Server Components entrypoint for the `react` package (ReactServer.js) so that it doesn't depend on the client entrypoint (React.js). I also renamed React.js to ReactClient.js to make the separation clearer. This structure will make it easier to add client-only and server-only features.
This commit is contained in:
@@ -58,5 +58,5 @@ export {
|
||||
useSyncExternalStore,
|
||||
useTransition,
|
||||
version,
|
||||
} from './src/React';
|
||||
} from './src/ReactClient';
|
||||
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';
|
||||
|
||||
@@ -57,9 +57,9 @@ export {
|
||||
useSyncExternalStore,
|
||||
useTransition,
|
||||
version,
|
||||
} from './src/React';
|
||||
} from './src/ReactClient';
|
||||
|
||||
import {useOptimistic} from './src/React';
|
||||
import {useOptimistic} from './src/ReactClient';
|
||||
|
||||
export function experimental_useOptimistic<S, A>(
|
||||
passthrough: S,
|
||||
|
||||
@@ -80,4 +80,4 @@ export {
|
||||
useState,
|
||||
useTransition,
|
||||
version,
|
||||
} from './src/React';
|
||||
} from './src/ReactClient';
|
||||
|
||||
@@ -56,5 +56,5 @@ export {
|
||||
useSyncExternalStore,
|
||||
useTransition,
|
||||
version,
|
||||
} from './src/React';
|
||||
} from './src/ReactClient';
|
||||
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';
|
||||
|
||||
@@ -47,4 +47,4 @@ export {
|
||||
useSyncExternalStore,
|
||||
useTransition,
|
||||
version,
|
||||
} from './src/React';
|
||||
} from './src/ReactClient';
|
||||
|
||||
@@ -26,9 +26,9 @@ import {Component, PureComponent} from './ReactBaseClasses';
|
||||
import {createRef} from './ReactCreateRef';
|
||||
import {forEach, map, count, toArray, only} from './ReactChildren';
|
||||
import {
|
||||
createElement as createElementProd,
|
||||
createFactory as createFactoryProd,
|
||||
cloneElement as cloneElementProd,
|
||||
createElement,
|
||||
createFactory,
|
||||
cloneElement,
|
||||
isValidElement,
|
||||
} from './ReactElement';
|
||||
import {createContext} from './ReactContext';
|
||||
@@ -61,27 +61,12 @@ import {
|
||||
useMemoCache,
|
||||
useOptimistic,
|
||||
} from './ReactHooks';
|
||||
import {
|
||||
createElementWithValidation,
|
||||
createFactoryWithValidation,
|
||||
cloneElementWithValidation,
|
||||
} from './ReactElementValidator';
|
||||
|
||||
import {createServerContext} from './ReactServerContext';
|
||||
import ReactSharedInternals from './ReactSharedInternalsClient';
|
||||
import {startTransition} from './ReactStartTransition';
|
||||
import {act} from './ReactAct';
|
||||
|
||||
// TODO: Move this branching into the other module instead and just re-export.
|
||||
const createElement: any = __DEV__
|
||||
? createElementWithValidation
|
||||
: createElementProd;
|
||||
const cloneElement: any = __DEV__
|
||||
? cloneElementWithValidation
|
||||
: cloneElementProd;
|
||||
const createFactory: any = __DEV__
|
||||
? createFactoryWithValidation
|
||||
: createFactoryProd;
|
||||
|
||||
const Children = {
|
||||
map,
|
||||
forEach,
|
||||
@@ -3,571 +3,30 @@
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import getComponentNameFromType from 'shared/getComponentNameFromType';
|
||||
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
|
||||
import assign from 'shared/assign';
|
||||
import hasOwnProperty from 'shared/hasOwnProperty';
|
||||
import {checkKeyStringCoercion} from 'shared/CheckStringCoercion';
|
||||
|
||||
import ReactCurrentOwner from './ReactCurrentOwner';
|
||||
|
||||
const RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true,
|
||||
};
|
||||
|
||||
let specialPropKeyWarningShown,
|
||||
specialPropRefWarningShown,
|
||||
didWarnAboutStringRefs;
|
||||
|
||||
if (__DEV__) {
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
if (__DEV__) {
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
const getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
if (__DEV__) {
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
const getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
const warnAboutAccessingKey = function () {
|
||||
if (__DEV__) {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
console.error(
|
||||
'%s: `key` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
displayName,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
const warnAboutAccessingRef = function () {
|
||||
if (__DEV__) {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
console.error(
|
||||
'%s: `ref` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
displayName,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function warnIfStringRefCannotBeAutoConverted(config) {
|
||||
if (__DEV__) {
|
||||
if (
|
||||
typeof config.ref === 'string' &&
|
||||
ReactCurrentOwner.current &&
|
||||
config.__self &&
|
||||
ReactCurrentOwner.current.stateNode !== config.__self
|
||||
) {
|
||||
const componentName = getComponentNameFromType(
|
||||
ReactCurrentOwner.current.type,
|
||||
);
|
||||
|
||||
if (!didWarnAboutStringRefs[componentName]) {
|
||||
console.error(
|
||||
'Component "%s" contains the string ref "%s". ' +
|
||||
'Support for string refs will be removed in a future major release. ' +
|
||||
'This case cannot be automatically converted to an arrow function. ' +
|
||||
'We ask you to manually fix this case by using useRef() or createRef() instead. ' +
|
||||
'Learn more about using refs safely here: ' +
|
||||
'https://reactjs.org/link/strict-mode-string-ref',
|
||||
componentName,
|
||||
config.ref,
|
||||
);
|
||||
didWarnAboutStringRefs[componentName] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
* @flow
|
||||
*/
|
||||
function ReactElement(type, key, ref, self, source, owner, props) {
|
||||
const element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
import {
|
||||
createElement as createElementProd,
|
||||
createFactory as createFactoryProd,
|
||||
cloneElement as cloneElementProd,
|
||||
} from './ReactElementProd';
|
||||
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner,
|
||||
};
|
||||
import {
|
||||
createElementWithValidation,
|
||||
createFactoryWithValidation,
|
||||
cloneElementWithValidation,
|
||||
} from './ReactElementValidator';
|
||||
|
||||
if (__DEV__) {
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {};
|
||||
export {isValidElement, cloneAndReplaceKey} from './ReactElementProd';
|
||||
|
||||
// To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false,
|
||||
});
|
||||
// self and source are DEV only properties.
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self,
|
||||
});
|
||||
// Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source,
|
||||
});
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
export function jsx(type, config, maybeKey) {
|
||||
let propName;
|
||||
|
||||
// Reserved names are extracted
|
||||
const props = {};
|
||||
|
||||
let key = null;
|
||||
let ref = null;
|
||||
|
||||
// Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
if (maybeKey !== undefined) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(maybeKey);
|
||||
}
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
}
|
||||
|
||||
// Remaining properties are added to a new props object
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve default props
|
||||
if (type && type.defaultProps) {
|
||||
const defaultProps = type.defaultProps;
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(
|
||||
type,
|
||||
key,
|
||||
ref,
|
||||
undefined,
|
||||
undefined,
|
||||
ReactCurrentOwner.current,
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
export function jsxDEV(type, config, maybeKey, source, self) {
|
||||
let propName;
|
||||
|
||||
// Reserved names are extracted
|
||||
const props = {};
|
||||
|
||||
let key = null;
|
||||
let ref = null;
|
||||
|
||||
// Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
if (maybeKey !== undefined) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(maybeKey);
|
||||
}
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
warnIfStringRefCannotBeAutoConverted(config);
|
||||
}
|
||||
|
||||
// Remaining properties are added to a new props object
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve default props
|
||||
if (type && type.defaultProps) {
|
||||
const defaultProps = type.defaultProps;
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
const displayName =
|
||||
typeof type === 'function'
|
||||
? type.displayName || type.name || 'Unknown'
|
||||
: type;
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(
|
||||
type,
|
||||
key,
|
||||
ref,
|
||||
self,
|
||||
source,
|
||||
ReactCurrentOwner.current,
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new ReactElement of the given type.
|
||||
* See https://reactjs.org/docs/react-api.html#createelement
|
||||
*/
|
||||
export function createElement(type, config, children) {
|
||||
let propName;
|
||||
|
||||
// Reserved names are extracted
|
||||
const props = {};
|
||||
|
||||
let key = null;
|
||||
let ref = null;
|
||||
let self = null;
|
||||
let source = null;
|
||||
|
||||
if (config != null) {
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
|
||||
if (__DEV__) {
|
||||
warnIfStringRefCannotBeAutoConverted(config);
|
||||
}
|
||||
}
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
self = config.__self === undefined ? null : config.__self;
|
||||
source = config.__source === undefined ? null : config.__source;
|
||||
// Remaining properties are added to a new props object
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Children can be more than one argument, and those are transferred onto
|
||||
// the newly allocated props object.
|
||||
const childrenLength = arguments.length - 2;
|
||||
if (childrenLength === 1) {
|
||||
props.children = children;
|
||||
} else if (childrenLength > 1) {
|
||||
const childArray = Array(childrenLength);
|
||||
for (let i = 0; i < childrenLength; i++) {
|
||||
childArray[i] = arguments[i + 2];
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (Object.freeze) {
|
||||
Object.freeze(childArray);
|
||||
}
|
||||
}
|
||||
props.children = childArray;
|
||||
}
|
||||
|
||||
// Resolve default props
|
||||
if (type && type.defaultProps) {
|
||||
const defaultProps = type.defaultProps;
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (key || ref) {
|
||||
const displayName =
|
||||
typeof type === 'function'
|
||||
? type.displayName || type.name || 'Unknown'
|
||||
: type;
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ReactElement(
|
||||
type,
|
||||
key,
|
||||
ref,
|
||||
self,
|
||||
source,
|
||||
ReactCurrentOwner.current,
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a function that produces ReactElements of a given type.
|
||||
* See https://reactjs.org/docs/react-api.html#createfactory
|
||||
*/
|
||||
export function createFactory(type) {
|
||||
const factory = createElement.bind(null, type);
|
||||
// Expose the type on the factory and the prototype so that it can be
|
||||
// easily accessed on elements. E.g. `<Foo />.type === Foo`.
|
||||
// This should not be named `constructor` since this may not be the function
|
||||
// that created the element, and it may not even be a constructor.
|
||||
// Legacy hook: remove it
|
||||
factory.type = type;
|
||||
return factory;
|
||||
}
|
||||
|
||||
export function cloneAndReplaceKey(oldElement, newKey) {
|
||||
const newElement = ReactElement(
|
||||
oldElement.type,
|
||||
newKey,
|
||||
oldElement.ref,
|
||||
oldElement._self,
|
||||
oldElement._source,
|
||||
oldElement._owner,
|
||||
oldElement.props,
|
||||
);
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone and return a new ReactElement using element as the starting point.
|
||||
* See https://reactjs.org/docs/react-api.html#cloneelement
|
||||
*/
|
||||
export function cloneElement(element, config, children) {
|
||||
if (element === null || element === undefined) {
|
||||
throw new Error(
|
||||
`React.cloneElement(...): The argument must be a React element, but you passed ${element}.`,
|
||||
);
|
||||
}
|
||||
|
||||
let propName;
|
||||
|
||||
// Original props are copied
|
||||
const props = assign({}, element.props);
|
||||
|
||||
// Reserved names are extracted
|
||||
let key = element.key;
|
||||
let ref = element.ref;
|
||||
// Self is preserved since the owner is preserved.
|
||||
const self = element._self;
|
||||
// Source is preserved since cloneElement is unlikely to be targeted by a
|
||||
// transpiler, and the original source is probably a better indicator of the
|
||||
// true owner.
|
||||
const source = element._source;
|
||||
|
||||
// Owner will be preserved, unless ref is overridden
|
||||
let owner = element._owner;
|
||||
|
||||
if (config != null) {
|
||||
if (hasValidRef(config)) {
|
||||
// Silently steal the ref from the parent.
|
||||
ref = config.ref;
|
||||
owner = ReactCurrentOwner.current;
|
||||
}
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
// Remaining properties override existing props
|
||||
let defaultProps;
|
||||
if (element.type && element.type.defaultProps) {
|
||||
defaultProps = element.type.defaultProps;
|
||||
}
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
if (config[propName] === undefined && defaultProps !== undefined) {
|
||||
// Resolve default props
|
||||
props[propName] = defaultProps[propName];
|
||||
} else {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Children can be more than one argument, and those are transferred onto
|
||||
// the newly allocated props object.
|
||||
const childrenLength = arguments.length - 2;
|
||||
if (childrenLength === 1) {
|
||||
props.children = children;
|
||||
} else if (childrenLength > 1) {
|
||||
const childArray = Array(childrenLength);
|
||||
for (let i = 0; i < childrenLength; i++) {
|
||||
childArray[i] = arguments[i + 2];
|
||||
}
|
||||
props.children = childArray;
|
||||
}
|
||||
|
||||
return ReactElement(element.type, key, ref, self, source, owner, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
export function isValidElement(object) {
|
||||
return (
|
||||
typeof object === 'object' &&
|
||||
object !== null &&
|
||||
object.$$typeof === REACT_ELEMENT_TYPE
|
||||
);
|
||||
}
|
||||
export const createElement: any = __DEV__
|
||||
? createElementWithValidation
|
||||
: createElementProd;
|
||||
export const cloneElement: any = __DEV__
|
||||
? cloneElementWithValidation
|
||||
: cloneElementProd;
|
||||
export const createFactory: any = __DEV__
|
||||
? createFactoryWithValidation
|
||||
: createFactoryProd;
|
||||
|
||||
@@ -0,0 +1,573 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import getComponentNameFromType from 'shared/getComponentNameFromType';
|
||||
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
|
||||
import assign from 'shared/assign';
|
||||
import hasOwnProperty from 'shared/hasOwnProperty';
|
||||
import {checkKeyStringCoercion} from 'shared/CheckStringCoercion';
|
||||
|
||||
import ReactCurrentOwner from './ReactCurrentOwner';
|
||||
|
||||
const RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true,
|
||||
};
|
||||
|
||||
let specialPropKeyWarningShown,
|
||||
specialPropRefWarningShown,
|
||||
didWarnAboutStringRefs;
|
||||
|
||||
if (__DEV__) {
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
if (__DEV__) {
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
const getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
if (__DEV__) {
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
const getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
const warnAboutAccessingKey = function () {
|
||||
if (__DEV__) {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
console.error(
|
||||
'%s: `key` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
displayName,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
const warnAboutAccessingRef = function () {
|
||||
if (__DEV__) {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
console.error(
|
||||
'%s: `ref` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
displayName,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function warnIfStringRefCannotBeAutoConverted(config) {
|
||||
if (__DEV__) {
|
||||
if (
|
||||
typeof config.ref === 'string' &&
|
||||
ReactCurrentOwner.current &&
|
||||
config.__self &&
|
||||
ReactCurrentOwner.current.stateNode !== config.__self
|
||||
) {
|
||||
const componentName = getComponentNameFromType(
|
||||
ReactCurrentOwner.current.type,
|
||||
);
|
||||
|
||||
if (!didWarnAboutStringRefs[componentName]) {
|
||||
console.error(
|
||||
'Component "%s" contains the string ref "%s". ' +
|
||||
'Support for string refs will be removed in a future major release. ' +
|
||||
'This case cannot be automatically converted to an arrow function. ' +
|
||||
'We ask you to manually fix this case by using useRef() or createRef() instead. ' +
|
||||
'Learn more about using refs safely here: ' +
|
||||
'https://reactjs.org/link/strict-mode-string-ref',
|
||||
componentName,
|
||||
config.ref,
|
||||
);
|
||||
didWarnAboutStringRefs[componentName] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
function ReactElement(type, key, ref, self, source, owner, props) {
|
||||
const element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner,
|
||||
};
|
||||
|
||||
if (__DEV__) {
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {};
|
||||
|
||||
// To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false,
|
||||
});
|
||||
// self and source are DEV only properties.
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self,
|
||||
});
|
||||
// Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source,
|
||||
});
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
export function jsx(type, config, maybeKey) {
|
||||
let propName;
|
||||
|
||||
// Reserved names are extracted
|
||||
const props = {};
|
||||
|
||||
let key = null;
|
||||
let ref = null;
|
||||
|
||||
// Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
if (maybeKey !== undefined) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(maybeKey);
|
||||
}
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
}
|
||||
|
||||
// Remaining properties are added to a new props object
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve default props
|
||||
if (type && type.defaultProps) {
|
||||
const defaultProps = type.defaultProps;
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(
|
||||
type,
|
||||
key,
|
||||
ref,
|
||||
undefined,
|
||||
undefined,
|
||||
ReactCurrentOwner.current,
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
export function jsxDEV(type, config, maybeKey, source, self) {
|
||||
let propName;
|
||||
|
||||
// Reserved names are extracted
|
||||
const props = {};
|
||||
|
||||
let key = null;
|
||||
let ref = null;
|
||||
|
||||
// Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
if (maybeKey !== undefined) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(maybeKey);
|
||||
}
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
warnIfStringRefCannotBeAutoConverted(config);
|
||||
}
|
||||
|
||||
// Remaining properties are added to a new props object
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve default props
|
||||
if (type && type.defaultProps) {
|
||||
const defaultProps = type.defaultProps;
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
const displayName =
|
||||
typeof type === 'function'
|
||||
? type.displayName || type.name || 'Unknown'
|
||||
: type;
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(
|
||||
type,
|
||||
key,
|
||||
ref,
|
||||
self,
|
||||
source,
|
||||
ReactCurrentOwner.current,
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new ReactElement of the given type.
|
||||
* See https://reactjs.org/docs/react-api.html#createelement
|
||||
*/
|
||||
export function createElement(type, config, children) {
|
||||
let propName;
|
||||
|
||||
// Reserved names are extracted
|
||||
const props = {};
|
||||
|
||||
let key = null;
|
||||
let ref = null;
|
||||
let self = null;
|
||||
let source = null;
|
||||
|
||||
if (config != null) {
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
|
||||
if (__DEV__) {
|
||||
warnIfStringRefCannotBeAutoConverted(config);
|
||||
}
|
||||
}
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
self = config.__self === undefined ? null : config.__self;
|
||||
source = config.__source === undefined ? null : config.__source;
|
||||
// Remaining properties are added to a new props object
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Children can be more than one argument, and those are transferred onto
|
||||
// the newly allocated props object.
|
||||
const childrenLength = arguments.length - 2;
|
||||
if (childrenLength === 1) {
|
||||
props.children = children;
|
||||
} else if (childrenLength > 1) {
|
||||
const childArray = Array(childrenLength);
|
||||
for (let i = 0; i < childrenLength; i++) {
|
||||
childArray[i] = arguments[i + 2];
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (Object.freeze) {
|
||||
Object.freeze(childArray);
|
||||
}
|
||||
}
|
||||
props.children = childArray;
|
||||
}
|
||||
|
||||
// Resolve default props
|
||||
if (type && type.defaultProps) {
|
||||
const defaultProps = type.defaultProps;
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (key || ref) {
|
||||
const displayName =
|
||||
typeof type === 'function'
|
||||
? type.displayName || type.name || 'Unknown'
|
||||
: type;
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ReactElement(
|
||||
type,
|
||||
key,
|
||||
ref,
|
||||
self,
|
||||
source,
|
||||
ReactCurrentOwner.current,
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a function that produces ReactElements of a given type.
|
||||
* See https://reactjs.org/docs/react-api.html#createfactory
|
||||
*/
|
||||
export function createFactory(type) {
|
||||
const factory = createElement.bind(null, type);
|
||||
// Expose the type on the factory and the prototype so that it can be
|
||||
// easily accessed on elements. E.g. `<Foo />.type === Foo`.
|
||||
// This should not be named `constructor` since this may not be the function
|
||||
// that created the element, and it may not even be a constructor.
|
||||
// Legacy hook: remove it
|
||||
factory.type = type;
|
||||
return factory;
|
||||
}
|
||||
|
||||
export function cloneAndReplaceKey(oldElement, newKey) {
|
||||
const newElement = ReactElement(
|
||||
oldElement.type,
|
||||
newKey,
|
||||
oldElement.ref,
|
||||
oldElement._self,
|
||||
oldElement._source,
|
||||
oldElement._owner,
|
||||
oldElement.props,
|
||||
);
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone and return a new ReactElement using element as the starting point.
|
||||
* See https://reactjs.org/docs/react-api.html#cloneelement
|
||||
*/
|
||||
export function cloneElement(element, config, children) {
|
||||
if (element === null || element === undefined) {
|
||||
throw new Error(
|
||||
`React.cloneElement(...): The argument must be a React element, but you passed ${element}.`,
|
||||
);
|
||||
}
|
||||
|
||||
let propName;
|
||||
|
||||
// Original props are copied
|
||||
const props = assign({}, element.props);
|
||||
|
||||
// Reserved names are extracted
|
||||
let key = element.key;
|
||||
let ref = element.ref;
|
||||
// Self is preserved since the owner is preserved.
|
||||
const self = element._self;
|
||||
// Source is preserved since cloneElement is unlikely to be targeted by a
|
||||
// transpiler, and the original source is probably a better indicator of the
|
||||
// true owner.
|
||||
const source = element._source;
|
||||
|
||||
// Owner will be preserved, unless ref is overridden
|
||||
let owner = element._owner;
|
||||
|
||||
if (config != null) {
|
||||
if (hasValidRef(config)) {
|
||||
// Silently steal the ref from the parent.
|
||||
ref = config.ref;
|
||||
owner = ReactCurrentOwner.current;
|
||||
}
|
||||
if (hasValidKey(config)) {
|
||||
if (__DEV__) {
|
||||
checkKeyStringCoercion(config.key);
|
||||
}
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
// Remaining properties override existing props
|
||||
let defaultProps;
|
||||
if (element.type && element.type.defaultProps) {
|
||||
defaultProps = element.type.defaultProps;
|
||||
}
|
||||
for (propName in config) {
|
||||
if (
|
||||
hasOwnProperty.call(config, propName) &&
|
||||
!RESERVED_PROPS.hasOwnProperty(propName)
|
||||
) {
|
||||
if (config[propName] === undefined && defaultProps !== undefined) {
|
||||
// Resolve default props
|
||||
props[propName] = defaultProps[propName];
|
||||
} else {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Children can be more than one argument, and those are transferred onto
|
||||
// the newly allocated props object.
|
||||
const childrenLength = arguments.length - 2;
|
||||
if (childrenLength === 1) {
|
||||
props.children = children;
|
||||
} else if (childrenLength > 1) {
|
||||
const childArray = Array(childrenLength);
|
||||
for (let i = 0; i < childrenLength; i++) {
|
||||
childArray[i] = arguments[i + 2];
|
||||
}
|
||||
props.children = childArray;
|
||||
}
|
||||
|
||||
return ReactElement(element.type, key, ref, self, source, owner, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
export function isValidElement(object) {
|
||||
return (
|
||||
typeof object === 'object' &&
|
||||
object !== null &&
|
||||
object.$$typeof === REACT_ELEMENT_TYPE
|
||||
);
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
createElement,
|
||||
cloneElement,
|
||||
jsxDEV,
|
||||
} from './ReactElement';
|
||||
} from './ReactElementProd';
|
||||
import {setExtraStackFrame} from './ReactDebugCurrentFrame';
|
||||
import {describeUnknownElementTypeFrameInDEV} from 'shared/ReactComponentStackFrame';
|
||||
import hasOwnProperty from 'shared/hasOwnProperty';
|
||||
|
||||
@@ -14,6 +14,43 @@ export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './R
|
||||
|
||||
export {default as __SECRET_SERVER_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './ReactServerSharedInternals';
|
||||
|
||||
import {forEach, map, count, toArray, only} from './ReactChildren';
|
||||
import {
|
||||
REACT_FRAGMENT_TYPE,
|
||||
REACT_PROFILER_TYPE,
|
||||
REACT_STRICT_MODE_TYPE,
|
||||
REACT_SUSPENSE_TYPE,
|
||||
REACT_DEBUG_TRACING_MODE_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
import {cloneElement, createElement, isValidElement} from './ReactElement';
|
||||
import {createRef} from './ReactCreateRef';
|
||||
import {createServerContext} from './ReactServerContext';
|
||||
import {
|
||||
use,
|
||||
useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
useDebugValue,
|
||||
useMemo,
|
||||
getCacheSignal,
|
||||
getCacheForType,
|
||||
} from './ReactHooks';
|
||||
import {forwardRef} from './ReactForwardRef';
|
||||
import {lazy} from './ReactLazy';
|
||||
import {memo} from './ReactMemo';
|
||||
import {cache} from './ReactCache';
|
||||
import {startTransition} from './ReactStartTransition';
|
||||
import {postpone} from './ReactPostpone';
|
||||
import version from 'shared/ReactVersion';
|
||||
|
||||
const Children = {
|
||||
map,
|
||||
forEach,
|
||||
count,
|
||||
toArray,
|
||||
only,
|
||||
};
|
||||
|
||||
// These are server-only
|
||||
export {
|
||||
taintUniqueValue as experimental_taintUniqueValue,
|
||||
@@ -22,10 +59,10 @@ export {
|
||||
|
||||
export {
|
||||
Children,
|
||||
Fragment,
|
||||
Profiler,
|
||||
StrictMode,
|
||||
Suspense,
|
||||
REACT_FRAGMENT_TYPE as Fragment,
|
||||
REACT_PROFILER_TYPE as Profiler,
|
||||
REACT_STRICT_MODE_TYPE as StrictMode,
|
||||
REACT_SUSPENSE_TYPE as Suspense,
|
||||
cloneElement,
|
||||
createElement,
|
||||
createRef,
|
||||
@@ -37,15 +74,15 @@ export {
|
||||
memo,
|
||||
cache,
|
||||
startTransition,
|
||||
unstable_DebugTracingMode,
|
||||
unstable_SuspenseList,
|
||||
unstable_getCacheSignal,
|
||||
unstable_getCacheForType,
|
||||
unstable_postpone,
|
||||
REACT_DEBUG_TRACING_MODE_TYPE as unstable_DebugTracingMode,
|
||||
REACT_SUSPENSE_TYPE as unstable_SuspenseList,
|
||||
getCacheSignal as unstable_getCacheSignal,
|
||||
getCacheForType as unstable_getCacheForType,
|
||||
postpone as unstable_postpone,
|
||||
useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
useDebugValue,
|
||||
useMemo,
|
||||
version,
|
||||
} from './React';
|
||||
};
|
||||
|
||||
@@ -14,12 +14,45 @@ export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './R
|
||||
|
||||
export {default as __SECRET_SERVER_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './ReactServerSharedInternals';
|
||||
|
||||
import {forEach, map, count, toArray, only} from './ReactChildren';
|
||||
import {
|
||||
REACT_FRAGMENT_TYPE,
|
||||
REACT_PROFILER_TYPE,
|
||||
REACT_STRICT_MODE_TYPE,
|
||||
REACT_SUSPENSE_TYPE,
|
||||
} from 'shared/ReactSymbols';
|
||||
import {cloneElement, createElement, isValidElement} from './ReactElement';
|
||||
import {createRef} from './ReactCreateRef';
|
||||
import {createServerContext} from './ReactServerContext';
|
||||
import {
|
||||
use,
|
||||
useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
useDebugValue,
|
||||
useMemo,
|
||||
} from './ReactHooks';
|
||||
import {forwardRef} from './ReactForwardRef';
|
||||
import {lazy} from './ReactLazy';
|
||||
import {memo} from './ReactMemo';
|
||||
import {cache} from './ReactCache';
|
||||
import {startTransition} from './ReactStartTransition';
|
||||
import version from 'shared/ReactVersion';
|
||||
|
||||
const Children = {
|
||||
map,
|
||||
forEach,
|
||||
count,
|
||||
toArray,
|
||||
only,
|
||||
};
|
||||
|
||||
export {
|
||||
Children,
|
||||
Fragment,
|
||||
Profiler,
|
||||
StrictMode,
|
||||
Suspense,
|
||||
REACT_FRAGMENT_TYPE as Fragment,
|
||||
REACT_PROFILER_TYPE as Profiler,
|
||||
REACT_STRICT_MODE_TYPE as StrictMode,
|
||||
REACT_SUSPENSE_TYPE as Suspense,
|
||||
cloneElement,
|
||||
createElement,
|
||||
createRef,
|
||||
@@ -37,4 +70,4 @@ export {
|
||||
useDebugValue,
|
||||
useMemo,
|
||||
version,
|
||||
} from './React';
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user