import getComponentNameFromType from 'shared/getComponentNameFromType';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import hasOwnProperty from 'shared/hasOwnProperty';
import assign from 'shared/assign';
import {
getIteratorFn,
REACT_ELEMENT_TYPE,
REACT_FRAGMENT_TYPE,
REACT_LAZY_TYPE,
} from 'shared/ReactSymbols';
import {checkKeyStringCoercion} from 'shared/CheckStringCoercion';
import isValidElementType from 'shared/isValidElementType';
import isArray from 'shared/isArray';
import {describeUnknownElementTypeFrameInDEV} from 'shared/ReactComponentStackFrame';
import {
enableRefAsProp,
disableStringRefs,
disableDefaultPropsExceptForClasses,
enableOwnerStacks,
} from 'shared/ReactFeatureFlags';
import {checkPropStringCoercion} from 'shared/CheckStringCoercion';
import {ClassComponent} from 'react-reconciler/src/ReactWorkTags';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
const REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference');
const createTask =
__DEV__ && enableOwnerStacks && console.createTask
?
console.createTask
: () => null;
function getTaskName(type) {
if (type === REACT_FRAGMENT_TYPE) {
return '<>';
}
if (
typeof type === 'object' &&
type !== null &&
type.$$typeof === REACT_LAZY_TYPE
) {
return '<...>';
}
try {
const name = getComponentNameFromType(type);
return name ? '<' + name + '>' : '<...>';
} catch (x) {
return '<...>';
}
}
function getOwner() {
if (__DEV__ || !disableStringRefs) {
const dispatcher = ReactSharedInternals.A;
if (dispatcher === null) {
return null;
}
return dispatcher.getOwner();
}
return null;
}
let specialPropKeyWarningShown;
let specialPropRefWarningShown;
let didWarnAboutStringRefs;
let didWarnAboutElementRef;
let didWarnAboutOldJSXRuntime;
if (__DEV__) {
didWarnAboutStringRefs = {};
didWarnAboutElementRef = {};
}
const enableFastJSXWithoutStringRefs = enableRefAsProp && disableStringRefs;
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 warnIfStringRefCannotBeAutoConverted(config, self) {
if (__DEV__) {
let owner;
if (
!disableStringRefs &&
typeof config.ref === 'string' &&
(owner = getOwner()) &&
self &&
owner.stateNode !== self
) {
const componentName = getComponentNameFromType(owner.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://react.dev/link/strict-mode-string-ref',
getComponentNameFromType(owner.type),
config.ref,
);
didWarnAboutStringRefs[componentName] = true;
}
}
}
}
function defineKeyPropWarningGetter(props, displayName) {
if (__DEV__) {
const warnAboutAccessingKey = function () {
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://react.dev/link/special-props)',
displayName,
);
}
};
warnAboutAccessingKey.isReactWarning = true;
Object.defineProperty(props, 'key', {
get: warnAboutAccessingKey,
configurable: true,
});
}
}
function defineRefPropWarningGetter(props, displayName) {
if (!enableRefAsProp) {
if (__DEV__) {
const warnAboutAccessingRef = function () {
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://react.dev/link/special-props)',
displayName,
);
}
};
warnAboutAccessingRef.isReactWarning = true;
Object.defineProperty(props, 'ref', {
get: warnAboutAccessingRef,
configurable: true,
});
}
}
}
function elementRefGetterWithDeprecationWarning() {
if (__DEV__) {
const componentName = getComponentNameFromType(this.type);
if (!didWarnAboutElementRef[componentName]) {
didWarnAboutElementRef[componentName] = true;
console.error(
'Accessing element.ref was removed in React 19. ref is now a ' +
'regular prop. It will be removed from the JSX Element ' +
'type in a future release.',
);
}
const refProp = this.props.ref;
return refProp !== undefined ? refProp : null;
}
}
function ReactElement(
type,
key,
_ref,
self,
source,
owner,
props,
debugStack,
debugTask,
) {
let ref;
if (enableRefAsProp) {
const refProp = props.ref;
ref = refProp !== undefined ? refProp : null;
} else {
ref = _ref;
}
let element;
if (__DEV__ && enableRefAsProp) {
element = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
props,
_owner: owner,
};
if (ref !== null) {
Object.defineProperty(element, 'ref', {
enumerable: false,
get: elementRefGetterWithDeprecationWarning,
});
} else {
Object.defineProperty(element, 'ref', {
enumerable: false,
value: null,
});
}
} else if (!__DEV__ && disableStringRefs) {
element = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
ref,
props,
};
} else {
element = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
ref,
props,
_owner: owner,
};
}
if (__DEV__) {
element._store = {};
Object.defineProperty(element._store, 'validated', {
configurable: false,
enumerable: false,
writable: true,
value: 0,
});
Object.defineProperty(element, '_debugInfo', {
configurable: false,
enumerable: false,
writable: true,
value: null,
});
if (enableOwnerStacks) {
Object.defineProperty(element, '_debugStack', {
configurable: false,
enumerable: false,
writable: true,
value: debugStack,
});
Object.defineProperty(element, '_debugTask', {
configurable: false,
enumerable: false,
writable: true,
value: debugTask,
});
}
if (Object.freeze) {
Object.freeze(element.props);
Object.freeze(element);
}
}
return element;
}
export function jsxProd(type, config, maybeKey) {
let key = null;
let ref = null;
if (maybeKey !== undefined) {
if (__DEV__) {
checkKeyStringCoercion(maybeKey);
}
key = '' + maybeKey;
}
if (hasValidKey(config)) {
if (__DEV__) {
checkKeyStringCoercion(config.key);
}
key = '' + config.key;
}
if (hasValidRef(config)) {
if (!enableRefAsProp) {
ref = config.ref;
if (!disableStringRefs) {
ref = coerceStringRef(ref, getOwner(), type);
}
}
}
let props;
if (
(enableFastJSXWithoutStringRefs ||
(enableRefAsProp && !('ref' in config))) &&
!('key' in config)
) {
props = config;
} else {
props = {};
for (const propName in config) {
if (propName !== 'key' && (enableRefAsProp || propName !== 'ref')) {
if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
props.ref = coerceStringRef(config[propName], getOwner(), type);
} else {
props[propName] = config[propName];
}
}
}
}
if (!disableDefaultPropsExceptForClasses) {
if (type && type.defaultProps) {
const defaultProps = type.defaultProps;
for (const propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
}
return ReactElement(
type,
key,
ref,
undefined,
undefined,
getOwner(),
props,
undefined,
undefined,
);
}
export function jsxProdSignatureRunningInDevWithDynamicChildren(
type,
config,
maybeKey,
source,
self,
) {
if (__DEV__) {
const isStaticChildren = false;
return jsxDEVImpl(
type,
config,
maybeKey,
isStaticChildren,
source,
self,
__DEV__ && enableOwnerStacks ? Error('react-stack-top-frame') : undefined,
__DEV__ && enableOwnerStacks ? createTask(getTaskName(type)) : undefined,
);
}
}
export function jsxProdSignatureRunningInDevWithStaticChildren(
type,
config,
maybeKey,
source,
self,
) {
if (__DEV__) {
const isStaticChildren = true;
return jsxDEVImpl(
type,
config,
maybeKey,
isStaticChildren,
source,
self,
__DEV__ && enableOwnerStacks ? Error('react-stack-top-frame') : undefined,
__DEV__ && enableOwnerStacks ? createTask(getTaskName(type)) : undefined,
);
}
}
const didWarnAboutKeySpread = {};
export function jsxDEV(type, config, maybeKey, isStaticChildren, source, self) {
return jsxDEVImpl(
type,
config,
maybeKey,
isStaticChildren,
source,
self,
__DEV__ && enableOwnerStacks ? Error('react-stack-top-frame') : undefined,
__DEV__ && enableOwnerStacks ? createTask(getTaskName(type)) : undefined,
);
}
function jsxDEVImpl(
type,
config,
maybeKey,
isStaticChildren,
source,
self,
debugStack,
debugTask,
) {
if (__DEV__) {
if (!enableOwnerStacks && !isValidElementType(type)) {
let info = '';
if (
type === undefined ||
(typeof type === 'object' &&
type !== null &&
Object.keys(type).length === 0)
) {
info +=
' You likely forgot to export your component from the file ' +
"it's defined in, or you might have mixed up default and named imports.";
}
let typeString;
if (type === null) {
typeString = 'null';
} else if (isArray(type)) {
typeString = 'array';
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
typeString = `<${getComponentNameFromType(type.type) || 'Unknown'} />`;
info =
' Did you accidentally export a JSX literal instead of a component?';
} else {
typeString = typeof type;
}
console.error(
'React.jsx: type is invalid -- expected a string (for ' +
'built-in components) or a class/function (for composite ' +
'components) but got: %s.%s',
typeString,
info,
);
} else {
const children = config.children;
if (children !== undefined) {
if (isStaticChildren) {
if (isArray(children)) {
for (let i = 0; i < children.length; i++) {
validateChildKeys(children[i], type);
}
if (Object.freeze) {
Object.freeze(children);
}
} else {
console.error(
'React.jsx: Static children should always be an array. ' +
'You are likely explicitly calling React.jsxs or React.jsxDEV. ' +
'Use the Babel transform instead.',
);
}
} else {
validateChildKeys(children, type);
}
}
}
if (hasOwnProperty.call(config, 'key')) {
const componentName = getComponentNameFromType(type);
const keys = Object.keys(config).filter(k => k !== 'key');
const beforeExample =
keys.length > 0
? '{key: someKey, ' + keys.join(': ..., ') + ': ...}'
: '{key: someKey}';
if (!didWarnAboutKeySpread[componentName + beforeExample]) {
const afterExample =
keys.length > 0 ? '{' + keys.join(': ..., ') + ': ...}' : '{}';
console.error(
'A props object containing a "key" prop is being spread into JSX:\n' +
' let props = %s;\n' +
' <%s {...props} />\n' +
'React keys must be passed directly to JSX without using spread:\n' +
' let props = %s;\n' +
' <%s key={someKey} {...props} />',
beforeExample,
componentName,
afterExample,
componentName,
);
didWarnAboutKeySpread[componentName + beforeExample] = true;
}
}
let key = null;
let ref = null;
if (maybeKey !== undefined) {
if (__DEV__) {
checkKeyStringCoercion(maybeKey);
}
key = '' + maybeKey;
}
if (hasValidKey(config)) {
if (__DEV__) {
checkKeyStringCoercion(config.key);
}
key = '' + config.key;
}
if (hasValidRef(config)) {
if (!enableRefAsProp) {
ref = config.ref;
if (!disableStringRefs) {
ref = coerceStringRef(ref, getOwner(), type);
}
}
if (!disableStringRefs) {
warnIfStringRefCannotBeAutoConverted(config, self);
}
}
let props;
if (
(enableFastJSXWithoutStringRefs ||
(enableRefAsProp && !('ref' in config))) &&
!('key' in config)
) {
props = config;
} else {
props = {};
for (const propName in config) {
if (propName !== 'key' && (enableRefAsProp || propName !== 'ref')) {
if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
props.ref = coerceStringRef(config[propName], getOwner(), type);
} else {
props[propName] = config[propName];
}
}
}
}
if (!disableDefaultPropsExceptForClasses) {
if (type && type.defaultProps) {
const defaultProps = type.defaultProps;
for (const propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
}
if (key || (!enableRefAsProp && ref)) {
const displayName =
typeof type === 'function'
? type.displayName || type.name || 'Unknown'
: type;
if (key) {
defineKeyPropWarningGetter(props, displayName);
}
if (!enableRefAsProp && ref) {
defineRefPropWarningGetter(props, displayName);
}
}
return ReactElement(
type,
key,
ref,
self,
source,
getOwner(),
props,
debugStack,
debugTask,
);
}
}
export function createElement(type, config, children) {
if (__DEV__) {
if (!enableOwnerStacks && !isValidElementType(type)) {
let info = '';
if (
type === undefined ||
(typeof type === 'object' &&
type !== null &&
Object.keys(type).length === 0)
) {
info +=
' You likely forgot to export your component from the file ' +
"it's defined in, or you might have mixed up default and named imports.";
}
let typeString;
if (type === null) {
typeString = 'null';
} else if (isArray(type)) {
typeString = 'array';
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
typeString = `<${getComponentNameFromType(type.type) || 'Unknown'} />`;
info =
' Did you accidentally export a JSX literal instead of a component?';
} else {
typeString = typeof type;
}
console.error(
'React.createElement: type is invalid -- expected a string (for ' +
'built-in components) or a class/function (for composite ' +
'components) but got: %s.%s',
typeString,
info,
);
} else {
for (let i = 2; i < arguments.length; i++) {
validateChildKeys(arguments[i], type);
}
}
}
let propName;
const props = {};
let key = null;
let ref = null;
if (config != null) {
if (__DEV__) {
if (
!didWarnAboutOldJSXRuntime &&
'__self' in config &&
!('key' in config)
) {
didWarnAboutOldJSXRuntime = true;
console.warn(
'Your app (or one of its dependencies) is using an outdated JSX ' +
'transform. Update to the modern JSX transform for ' +
'faster performance: https://react.dev/link/new-jsx-transform',
);
}
}
if (hasValidRef(config)) {
if (!enableRefAsProp) {
ref = config.ref;
if (!disableStringRefs) {
ref = coerceStringRef(ref, getOwner(), type);
}
}
if (__DEV__ && !disableStringRefs) {
warnIfStringRefCannotBeAutoConverted(config, config.__self);
}
}
if (hasValidKey(config)) {
if (__DEV__) {
checkKeyStringCoercion(config.key);
}
key = '' + config.key;
}
for (propName in config) {
if (
hasOwnProperty.call(config, propName) &&
propName !== 'key' &&
(enableRefAsProp || propName !== 'ref') &&
propName !== '__self' &&
propName !== '__source'
) {
if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
props.ref = coerceStringRef(config[propName], getOwner(), type);
} else {
props[propName] = config[propName];
}
}
}
}
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;
}
if (type && type.defaultProps) {
const defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
if (__DEV__) {
if (key || (!enableRefAsProp && ref)) {
const displayName =
typeof type === 'function'
? type.displayName || type.name || 'Unknown'
: type;
if (key) {
defineKeyPropWarningGetter(props, displayName);
}
if (!enableRefAsProp && ref) {
defineRefPropWarningGetter(props, displayName);
}
}
}
return ReactElement(
type,
key,
ref,
undefined,
undefined,
getOwner(),
props,
__DEV__ && enableOwnerStacks ? Error('react-stack-top-frame') : undefined,
__DEV__ && enableOwnerStacks ? createTask(getTaskName(type)) : undefined,
);
}
export function cloneAndReplaceKey(oldElement, newKey) {
const clonedElement = ReactElement(
oldElement.type,
newKey,
enableRefAsProp ? null : oldElement.ref,
undefined,
undefined,
!__DEV__ && disableStringRefs ? undefined : oldElement._owner,
oldElement.props,
__DEV__ && enableOwnerStacks ? oldElement._debugStack : undefined,
__DEV__ && enableOwnerStacks ? oldElement._debugTask : undefined,
);
if (__DEV__) {
clonedElement._store.validated = oldElement._store.validated;
}
return clonedElement;
}
export function cloneElement(element, config, children) {
if (element === null || element === undefined) {
throw new Error(
`The argument must be a React element, but you passed ${element}.`,
);
}
let propName;
const props = assign({}, element.props);
let key = element.key;
let ref = enableRefAsProp ? null : element.ref;
let owner = !__DEV__ && disableStringRefs ? undefined : element._owner;
if (config != null) {
if (hasValidRef(config)) {
owner = __DEV__ || !disableStringRefs ? getOwner() : undefined;
if (!enableRefAsProp) {
ref = config.ref;
if (!disableStringRefs) {
ref = coerceStringRef(ref, owner, element.type);
}
}
}
if (hasValidKey(config)) {
if (__DEV__) {
checkKeyStringCoercion(config.key);
}
key = '' + config.key;
}
let defaultProps;
if (
!disableDefaultPropsExceptForClasses &&
element.type &&
element.type.defaultProps
) {
defaultProps = element.type.defaultProps;
}
for (propName in config) {
if (
hasOwnProperty.call(config, propName) &&
propName !== 'key' &&
(enableRefAsProp || propName !== 'ref') &&
propName !== '__self' &&
propName !== '__source' &&
!(enableRefAsProp && propName === 'ref' && config.ref === undefined)
) {
if (
!disableDefaultPropsExceptForClasses &&
config[propName] === undefined &&
defaultProps !== undefined
) {
props[propName] = defaultProps[propName];
} else {
if (enableRefAsProp && !disableStringRefs && propName === 'ref') {
props.ref = coerceStringRef(config[propName], owner, element.type);
} else {
props[propName] = config[propName];
}
}
}
}
}
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;
}
const clonedElement = ReactElement(
element.type,
key,
ref,
undefined,
undefined,
owner,
props,
__DEV__ && enableOwnerStacks ? element._debugStack : undefined,
__DEV__ && enableOwnerStacks ? element._debugTask : undefined,
);
for (let i = 2; i < arguments.length; i++) {
validateChildKeys(arguments[i], clonedElement.type);
}
return clonedElement;
}
function validateChildKeys(node, parentType) {
if (__DEV__) {
if (enableOwnerStacks) {
if (isValidElement(node)) {
if (node._store) {
node._store.validated = 1;
}
}
return;
}
if (typeof node !== 'object' || !node) {
return;
}
if (node.$$typeof === REACT_CLIENT_REFERENCE) {
} else if (isArray(node)) {
for (let i = 0; i < node.length; i++) {
const child = node[i];
if (isValidElement(child)) {
validateExplicitKey(child, parentType);
}
}
} else if (isValidElement(node)) {
if (node._store) {
node._store.validated = 1;
}
} else {
const iteratorFn = getIteratorFn(node);
if (typeof iteratorFn === 'function') {
if (iteratorFn !== node.entries) {
const iterator = iteratorFn.call(node);
if (iterator !== node) {
let step;
while (!(step = iterator.next()).done) {
if (isValidElement(step.value)) {
validateExplicitKey(step.value, parentType);
}
}
}
}
}
}
}
}
export function isValidElement(object) {
return (
typeof object === 'object' &&
object !== null &&
object.$$typeof === REACT_ELEMENT_TYPE
);
}
const ownerHasKeyUseWarning = {};
function validateExplicitKey(element, parentType) {
if (enableOwnerStacks) {
return;
}
if (__DEV__) {
if (!element._store || element._store.validated || element.key != null) {
return;
}
element._store.validated = 1;
const currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
return;
}
ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
let childOwner = '';
if (element && element._owner != null && element._owner !== getOwner()) {
let ownerName = null;
if (typeof element._owner.tag === 'number') {
ownerName = getComponentNameFromType(element._owner.type);
} else if (typeof element._owner.name === 'string') {
ownerName = element._owner.name;
}
childOwner = ` It was passed a child from ${ownerName}.`;
}
const prevGetCurrentStack = ReactSharedInternals.getCurrentStack;
ReactSharedInternals.getCurrentStack = function () {
const owner = element._owner;
let stack = describeUnknownElementTypeFrameInDEV(
element.type,
owner ? owner.type : null,
);
if (prevGetCurrentStack) {
stack += prevGetCurrentStack() || '';
}
return stack;
};
console.error(
'Each child in a list should have a unique "key" prop.' +
'%s%s See https://react.dev/link/warning-keys for more information.',
currentComponentErrorInfo,
childOwner,
);
ReactSharedInternals.getCurrentStack = prevGetCurrentStack;
}
}
function getCurrentComponentErrorInfo(parentType) {
if (__DEV__) {
let info = '';
const owner = getOwner();
if (owner) {
const name = getComponentNameFromType(owner.type);
if (name) {
info = '\n\nCheck the render method of `' + name + '`.';
}
}
if (!info) {
const parentName = getComponentNameFromType(parentType);
if (parentName) {
info = `\n\nCheck the top-level render call using <${parentName}>.`;
}
}
return info;
}
}
function coerceStringRef(mixedRef, owner, type) {
if (disableStringRefs) {
return mixedRef;
}
let stringRef;
if (typeof mixedRef === 'string') {
stringRef = mixedRef;
} else {
if (typeof mixedRef === 'number' || typeof mixedRef === 'boolean') {
if (__DEV__) {
checkPropStringCoercion(mixedRef, 'ref');
}
stringRef = '' + mixedRef;
} else {
return mixedRef;
}
}
const callback = stringRefAsCallbackRef.bind(null, stringRef, type, owner);
callback.__stringRef = stringRef;
callback.__type = type;
callback.__owner = owner;
return callback;
}
function stringRefAsCallbackRef(stringRef, type, owner, value) {
if (disableStringRefs) {
return;
}
if (!owner) {
throw new Error(
`Element ref was specified as a string (${stringRef}) but no owner was set. This could happen for one of` +
' the following reasons:\n' +
'1. You may be adding a ref to a function component\n' +
"2. You may be adding a ref to a component that was not created inside a component's render method\n" +
'3. You have multiple copies of React loaded\n' +
'See https://react.dev/link/refs-must-have-owner for more information.',
);
}
if (owner.tag !== ClassComponent) {
throw new Error(
'Function components cannot have string refs. ' +
'We recommend using useRef() instead. ' +
'Learn more about using refs safely here: ' +
'https://react.dev/link/strict-mode-string-ref',
);
}
if (__DEV__) {
if (
!(typeof type === 'function' && !isReactClass(type))
) {
const componentName = getComponentNameFromFiber(owner) || 'Component';
if (!didWarnAboutStringRefs[componentName]) {
console.error(
'Component "%s" contains the string ref "%s". Support for string refs ' +
'will be removed in a future major release. We recommend using ' +
'useRef() or createRef() instead. ' +
'Learn more about using refs safely here: ' +
'https://react.dev/link/strict-mode-string-ref',
componentName,
stringRef,
);
didWarnAboutStringRefs[componentName] = true;
}
}
}
const inst = owner.stateNode;
if (!inst) {
throw new Error(
`Missing owner for string ref ${stringRef}. This error is likely caused by a ` +
'bug in React. Please file an issue.',
);
}
const refs = inst.refs;
if (value === null) {
delete refs[stringRef];
} else {
refs[stringRef] = value;
}
}
function isReactClass(type) {
return type.prototype && type.prototype.isReactComponent;
}