@@ -112,8 +112,11 @@ if (__DEV__) {
112
112
enableRefAsProp = dynamicFeatureFlags . enableRefAsProp ,
113
113
disableDefaultPropsExceptForClasses =
114
114
dynamicFeatureFlags . disableDefaultPropsExceptForClasses ; // On WWW, false is used for a new modern build.
115
+ // because JSX is an extremely hot path.
115
116
116
- function getWrappedName ( outerType , innerType , wrapperName ) {
117
+ var disableStringRefs = false ;
118
+
119
+ function getWrappedName$1 ( outerType , innerType , wrapperName ) {
117
120
var displayName = outerType . displayName ;
118
121
119
122
if ( displayName ) {
@@ -126,7 +129,7 @@ if (__DEV__) {
126
129
: wrapperName ;
127
130
} // Keep in sync with react-reconciler/getComponentNameFromFiber
128
131
129
- function getContextName ( type ) {
132
+ function getContextName$1 ( type ) {
130
133
return type . displayName || "Context" ;
131
134
}
132
135
@@ -193,28 +196,28 @@ if (__DEV__) {
193
196
return null ;
194
197
} else {
195
198
var provider = type ;
196
- return getContextName ( provider . _context ) + ".Provider" ;
199
+ return getContextName$1 ( provider . _context ) + ".Provider" ;
197
200
}
198
201
199
202
case REACT_CONTEXT_TYPE :
200
203
var context = type ;
201
204
202
205
if ( enableRenderableContext ) {
203
- return getContextName ( context ) + ".Provider" ;
206
+ return getContextName$1 ( context ) + ".Provider" ;
204
207
} else {
205
- return getContextName ( context ) + ".Consumer" ;
208
+ return getContextName$1 ( context ) + ".Consumer" ;
206
209
}
207
210
208
211
case REACT_CONSUMER_TYPE :
209
212
if ( enableRenderableContext ) {
210
213
var consumer = type ;
211
- return getContextName ( consumer . _context ) + ".Consumer" ;
214
+ return getContextName$1 ( consumer . _context ) + ".Consumer" ;
212
215
} else {
213
216
return null ;
214
217
}
215
218
216
219
case REACT_FORWARD_REF_TYPE :
217
- return getWrappedName ( type , type . render , "ForwardRef" ) ;
220
+ return getWrappedName$1 ( type , type . render , "ForwardRef" ) ;
218
221
219
222
case REACT_MEMO_TYPE :
220
223
var outerName = type . displayName || null ;
@@ -323,6 +326,20 @@ if (__DEV__) {
323
326
}
324
327
}
325
328
}
329
+ function checkPropStringCoercion ( value , propName ) {
330
+ {
331
+ if ( willCoercionThrow ( value ) ) {
332
+ error (
333
+ "The provided `%s` prop is an unsupported type %s." +
334
+ " This value must be coerced to a string before using it here." ,
335
+ propName ,
336
+ typeName ( value )
337
+ ) ;
338
+
339
+ return testStringCoercion ( value ) ; // throw (to help callers find troubleshooting comments)
340
+ }
341
+ }
342
+ }
326
343
327
344
var REACT_CLIENT_REFERENCE$1 = Symbol . for ( "react.client.reference" ) ;
328
345
function isValidElementType ( type ) {
@@ -802,6 +819,158 @@ if (__DEV__) {
802
819
return "" ;
803
820
}
804
821
822
+ var FunctionComponent = 0 ;
823
+ var ClassComponent = 1 ;
824
+ var HostRoot = 3 ; // Root of a host tree. Could be nested inside another node.
825
+
826
+ var HostPortal = 4 ; // A subtree. Could be an entry point to a different renderer.
827
+
828
+ var HostComponent = 5 ;
829
+ var HostText = 6 ;
830
+ var Fragment = 7 ;
831
+ var Mode = 8 ;
832
+ var ContextConsumer = 9 ;
833
+ var ContextProvider = 10 ;
834
+ var ForwardRef = 11 ;
835
+ var Profiler = 12 ;
836
+ var SuspenseComponent = 13 ;
837
+ var MemoComponent = 14 ;
838
+ var SimpleMemoComponent = 15 ;
839
+ var LazyComponent = 16 ;
840
+ var IncompleteClassComponent = 17 ;
841
+ var DehydratedFragment = 18 ;
842
+ var SuspenseListComponent = 19 ;
843
+ var ScopeComponent = 21 ;
844
+ var OffscreenComponent = 22 ;
845
+ var LegacyHiddenComponent = 23 ;
846
+ var CacheComponent = 24 ;
847
+ var TracingMarkerComponent = 25 ;
848
+ var HostHoistable = 26 ;
849
+ var HostSingleton = 27 ;
850
+ var IncompleteFunctionComponent = 28 ;
851
+
852
+ function getWrappedName ( outerType , innerType , wrapperName ) {
853
+ var functionName = innerType . displayName || innerType . name || "" ;
854
+ return (
855
+ outerType . displayName ||
856
+ ( functionName !== ""
857
+ ? wrapperName + "(" + functionName + ")"
858
+ : wrapperName )
859
+ ) ;
860
+ } // Keep in sync with shared/getComponentNameFromType
861
+
862
+ function getContextName ( type ) {
863
+ return type . displayName || "Context" ;
864
+ }
865
+
866
+ function getComponentNameFromFiber ( fiber ) {
867
+ var tag = fiber . tag ,
868
+ type = fiber . type ;
869
+
870
+ switch ( tag ) {
871
+ case CacheComponent :
872
+ return "Cache" ;
873
+
874
+ case ContextConsumer :
875
+ if ( enableRenderableContext ) {
876
+ var consumer = type ;
877
+ return getContextName ( consumer . _context ) + ".Consumer" ;
878
+ } else {
879
+ var context = type ;
880
+ return getContextName ( context ) + ".Consumer" ;
881
+ }
882
+
883
+ case ContextProvider :
884
+ if ( enableRenderableContext ) {
885
+ var _context = type ;
886
+ return getContextName ( _context ) + ".Provider" ;
887
+ } else {
888
+ var provider = type ;
889
+ return getContextName ( provider . _context ) + ".Provider" ;
890
+ }
891
+
892
+ case DehydratedFragment :
893
+ return "DehydratedFragment" ;
894
+
895
+ case ForwardRef :
896
+ return getWrappedName ( type , type . render , "ForwardRef" ) ;
897
+
898
+ case Fragment :
899
+ return "Fragment" ;
900
+
901
+ case HostHoistable :
902
+ case HostSingleton :
903
+ case HostComponent :
904
+ // Host component type is the display name (e.g. "div", "View")
905
+ return type ;
906
+
907
+ case HostPortal :
908
+ return "Portal" ;
909
+
910
+ case HostRoot :
911
+ return "Root" ;
912
+
913
+ case HostText :
914
+ return "Text" ;
915
+
916
+ case LazyComponent :
917
+ // Name comes from the type in this case; we don't have a tag.
918
+ return getComponentNameFromType ( type ) ;
919
+
920
+ case Mode :
921
+ if ( type === REACT_STRICT_MODE_TYPE ) {
922
+ // Don't be less specific than shared/getComponentNameFromType
923
+ return "StrictMode" ;
924
+ }
925
+
926
+ return "Mode" ;
927
+
928
+ case OffscreenComponent :
929
+ return "Offscreen" ;
930
+
931
+ case Profiler :
932
+ return "Profiler" ;
933
+
934
+ case ScopeComponent :
935
+ return "Scope" ;
936
+
937
+ case SuspenseComponent :
938
+ return "Suspense" ;
939
+
940
+ case SuspenseListComponent :
941
+ return "SuspenseList" ;
942
+
943
+ case TracingMarkerComponent :
944
+ return "TracingMarker" ;
945
+ // The display name for these tags come from the user-provided type:
946
+
947
+ case IncompleteClassComponent :
948
+ case IncompleteFunctionComponent :
949
+
950
+ // Fallthrough
951
+
952
+ case ClassComponent :
953
+ case FunctionComponent :
954
+ case MemoComponent :
955
+ case SimpleMemoComponent :
956
+ if ( typeof type === "function" ) {
957
+ return type . displayName || type . name || null ;
958
+ }
959
+
960
+ if ( typeof type === "string" ) {
961
+ return type ;
962
+ }
963
+
964
+ break ;
965
+
966
+ case LegacyHiddenComponent : {
967
+ return "LegacyHidden" ;
968
+ }
969
+ }
970
+
971
+ return null ;
972
+ }
973
+
805
974
var ReactCurrentOwner = ReactSharedInternals . ReactCurrentOwner ;
806
975
var ReactDebugCurrentFrame = ReactSharedInternals . ReactDebugCurrentFrame ;
807
976
var REACT_CLIENT_REFERENCE = Symbol . for ( "react.client.reference" ) ;
@@ -1217,6 +1386,10 @@ if (__DEV__) {
1217
1386
if ( hasValidRef ( config ) ) {
1218
1387
if ( ! enableRefAsProp ) {
1219
1388
ref = config . ref ;
1389
+
1390
+ {
1391
+ ref = coerceStringRef ( ref , ReactCurrentOwner . current , type ) ;
1392
+ }
1220
1393
}
1221
1394
1222
1395
{
@@ -1230,7 +1403,15 @@ if (__DEV__) {
1230
1403
propName !== "key" &&
1231
1404
( enableRefAsProp || propName !== "ref" )
1232
1405
) {
1233
- props [ propName ] = config [ propName ] ;
1406
+ if ( enableRefAsProp && ! disableStringRefs && propName === "ref" ) {
1407
+ props . ref = coerceStringRef (
1408
+ config [ propName ] ,
1409
+ ReactCurrentOwner . current ,
1410
+ type
1411
+ ) ;
1412
+ } else {
1413
+ props [ propName ] = config [ propName ] ;
1414
+ }
1234
1415
}
1235
1416
}
1236
1417
@@ -1488,6 +1669,96 @@ if (__DEV__) {
1488
1669
}
1489
1670
}
1490
1671
1672
+ function coerceStringRef ( mixedRef , owner , type ) {
1673
+ var stringRef ;
1674
+
1675
+ if ( typeof mixedRef === "string" ) {
1676
+ stringRef = mixedRef ;
1677
+ } else {
1678
+ if ( typeof mixedRef === "number" || typeof mixedRef === "boolean" ) {
1679
+ {
1680
+ checkPropStringCoercion ( mixedRef , "ref" ) ;
1681
+ }
1682
+
1683
+ stringRef = "" + mixedRef ;
1684
+ } else {
1685
+ return mixedRef ;
1686
+ }
1687
+ }
1688
+
1689
+ return stringRefAsCallbackRef . bind ( null , stringRef , type , owner ) ;
1690
+ }
1691
+
1692
+ function stringRefAsCallbackRef ( stringRef , type , owner , value ) {
1693
+ if ( ! owner ) {
1694
+ throw new Error (
1695
+ "Element ref was specified as a string (" +
1696
+ stringRef +
1697
+ ") but no owner was set. This could happen for one of" +
1698
+ " the following reasons:\n" +
1699
+ "1. You may be adding a ref to a function component\n" +
1700
+ "2. You may be adding a ref to a component that was not created inside a component's render method\n" +
1701
+ "3. You have multiple copies of React loaded\n" +
1702
+ "See https://react.dev/link/refs-must-have-owner for more information."
1703
+ ) ;
1704
+ }
1705
+
1706
+ if ( owner . tag !== ClassComponent ) {
1707
+ throw new Error (
1708
+ "Function components cannot have string refs. " +
1709
+ "We recommend using useRef() instead. " +
1710
+ "Learn more about using refs safely here: " +
1711
+ "https://react.dev/link/strict-mode-string-ref"
1712
+ ) ;
1713
+ }
1714
+
1715
+ {
1716
+ if (
1717
+ // Will already warn with "Function components cannot be given refs"
1718
+ ! ( typeof type === "function" && ! isReactClass ( type ) )
1719
+ ) {
1720
+ var componentName = getComponentNameFromFiber ( owner ) || "Component" ;
1721
+
1722
+ if ( ! didWarnAboutStringRefs [ componentName ] ) {
1723
+ error (
1724
+ 'Component "%s" contains the string ref "%s". Support for string refs ' +
1725
+ "will be removed in a future major release. We recommend using " +
1726
+ "useRef() or createRef() instead. " +
1727
+ "Learn more about using refs safely here: " +
1728
+ "https://react.dev/link/strict-mode-string-ref" ,
1729
+ componentName ,
1730
+ stringRef
1731
+ ) ;
1732
+
1733
+ didWarnAboutStringRefs [ componentName ] = true ;
1734
+ }
1735
+ }
1736
+ }
1737
+
1738
+ var inst = owner . stateNode ;
1739
+
1740
+ if ( ! inst ) {
1741
+ throw new Error (
1742
+ "Missing owner for string ref " +
1743
+ stringRef +
1744
+ ". This error is likely caused by a " +
1745
+ "bug in React. Please file an issue."
1746
+ ) ;
1747
+ }
1748
+
1749
+ var refs = inst . refs ;
1750
+
1751
+ if ( value === null ) {
1752
+ delete refs [ stringRef ] ;
1753
+ } else {
1754
+ refs [ stringRef ] = value ;
1755
+ }
1756
+ }
1757
+
1758
+ function isReactClass ( type ) {
1759
+ return type . prototype && type . prototype . isReactComponent ;
1760
+ }
1761
+
1491
1762
var jsxDEV = jsxDEV$1 ;
1492
1763
1493
1764
exports . Fragment = REACT_FRAGMENT_TYPE ;
0 commit comments