Skip to content

Commit fc46af0

Browse files
committed
Move ref type check to receiver (#28464)
The runtime contains a type check to determine if a user-provided ref is a valid type — a function or object (or a string, when `disableStringRefs` is off). This currently happens during child reconciliation. This changes it to happen only when the ref is passed to the component that the ref is being attached to. This is a continuation of the "ref as prop" change — until you actually pass a ref to a HostComponent, class, etc, ref is a normal prop that has no special behavior. DiffTrain build for commit 2f8f776.
1 parent dbab28d commit fc46af0

File tree

13 files changed

+220
-214
lines changed

13 files changed

+220
-214
lines changed

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js

+28-30
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<c7f09b0ccfd717d023bd590c0cbfdace>>
10+
* @generated SignedSource<<514c453e36455da8cb22e0c8c9169c24>>
1111
*/
1212

1313
"use strict";
@@ -5067,18 +5067,17 @@ if (__DEV__) {
50675067
element,
50685068
mixedRef
50695069
) {
5070+
{
5071+
checkPropStringCoercion(mixedRef, "ref");
5072+
}
5073+
5074+
var stringRef = "" + mixedRef;
50705075
var owner = element._owner;
50715076

50725077
if (!owner) {
5073-
if (typeof mixedRef !== "string") {
5074-
throw new Error(
5075-
"Expected ref to be a function, a string, an object returned by React.createRef(), or null."
5076-
);
5077-
}
5078-
50795078
throw new Error(
50805079
"Element ref was specified as a string (" +
5081-
mixedRef +
5080+
stringRef +
50825081
") but no owner was set. This could happen for one of" +
50835082
" the following reasons:\n" +
50845083
"1. You may be adding a ref to a function component\n" +
@@ -5095,15 +5094,8 @@ if (__DEV__) {
50955094
"Learn more about using refs safely here: " +
50965095
"https://reactjs.org/link/strict-mode-string-ref"
50975096
);
5098-
} // At this point, we know the ref isn't an object or function but it could
5099-
// be a number. Coerce it to a string.
5100-
5101-
{
5102-
checkPropStringCoercion(mixedRef, "ref");
51035097
}
51045098

5105-
var stringRef = "" + mixedRef;
5106-
51075099
{
51085100
if (
51095101
// Will already warn with "Function components cannot be given refs"
@@ -5175,12 +5167,10 @@ if (__DEV__) {
51755167
var coercedRef;
51765168

51775169
if (
5178-
mixedRef !== null &&
5179-
typeof mixedRef !== "function" &&
5180-
typeof mixedRef !== "object"
5170+
typeof mixedRef === "string" ||
5171+
typeof mixedRef === "number" ||
5172+
typeof mixedRef === "boolean"
51815173
) {
5182-
// Assume this is a string ref. If it's not, then this will throw an error
5183-
// to the user.
51845174
coercedRef = convertStringRefToCallbackRef(
51855175
returnFiber,
51865176
current,
@@ -13232,17 +13222,25 @@ if (__DEV__) {
1323213222
}
1323313223

1323413224
function markRef(current, workInProgress) {
13235-
// TODO: This is also where we should check the type of the ref and error if
13236-
// an invalid one is passed, instead of during child reconcilation.
13225+
// TODO: Check props.ref instead of fiber.ref when enableRefAsProp is on.
1323713226
var ref = workInProgress.ref;
1323813227

13239-
if (
13240-
(current === null && ref !== null) ||
13241-
(current !== null && current.ref !== ref)
13242-
) {
13243-
// Schedule a Ref effect
13244-
workInProgress.flags |= Ref;
13245-
workInProgress.flags |= RefStatic;
13228+
if (ref === null) {
13229+
if (current !== null && current.ref !== null) {
13230+
// Schedule a Ref effect
13231+
workInProgress.flags |= Ref | RefStatic;
13232+
}
13233+
} else {
13234+
if (typeof ref !== "function" && typeof ref !== "object") {
13235+
throw new Error(
13236+
"Expected ref to be a function, an object returned by React.createRef(), or undefined/null."
13237+
);
13238+
}
13239+
13240+
if (current === null || current.ref !== ref) {
13241+
// Schedule a Ref effect
13242+
workInProgress.flags |= Ref | RefStatic;
13243+
}
1324613244
}
1324713245
}
1324813246

@@ -25735,7 +25733,7 @@ if (__DEV__) {
2573525733
return root;
2573625734
}
2573725735

25738-
var ReactVersion = "18.3.0-canary-bb4b147da-20240229";
25736+
var ReactVersion = "18.3.0-canary-2f8f77602-20240229";
2573925737

2574025738
// Might add PROFILE later.
2574125739

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js

+22-20
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<74c9b737997575eb03bf09dfe096e458>>
10+
* @generated SignedSource<<c9fcc719668d07b3a623f14e395c32b8>>
1111
*/
1212

1313
"use strict";
@@ -1464,24 +1464,19 @@ function convertStringRefToCallbackRef(
14641464
var refs = inst.refs;
14651465
null === value ? delete refs[stringRef] : (refs[stringRef] = value);
14661466
}
1467+
var stringRef = "" + mixedRef;
14671468
returnFiber = element._owner;
1468-
if (!returnFiber) {
1469-
if ("string" !== typeof mixedRef)
1470-
throw Error(
1471-
"Expected ref to be a function, a string, an object returned by React.createRef(), or null."
1472-
);
1469+
if (!returnFiber)
14731470
throw Error(
14741471
"Element ref was specified as a string (" +
1475-
mixedRef +
1472+
stringRef +
14761473
") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://reactjs.org/link/refs-must-have-owner for more information."
14771474
);
1478-
}
14791475
if (1 !== returnFiber.tag)
14801476
throw Error(
14811477
"Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref"
14821478
);
1483-
var stringRef = "" + mixedRef,
1484-
inst = returnFiber.stateNode;
1479+
var inst = returnFiber.stateNode;
14851480
if (!inst)
14861481
throw Error(
14871482
"Missing owner for string ref " +
@@ -1501,9 +1496,9 @@ function convertStringRefToCallbackRef(
15011496
function coerceRef(returnFiber, current, workInProgress, element) {
15021497
var mixedRef = element.ref;
15031498
returnFiber =
1504-
null !== mixedRef &&
1505-
"function" !== typeof mixedRef &&
1506-
"object" !== typeof mixedRef
1499+
"string" === typeof mixedRef ||
1500+
"number" === typeof mixedRef ||
1501+
"boolean" === typeof mixedRef
15071502
? convertStringRefToCallbackRef(returnFiber, current, element, mixedRef)
15081503
: mixedRef;
15091504
workInProgress.ref = returnFiber;
@@ -3986,11 +3981,18 @@ function deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes) {
39863981
}
39873982
function markRef(current, workInProgress) {
39883983
var ref = workInProgress.ref;
3989-
if (
3990-
(null === current && null !== ref) ||
3991-
(null !== current && current.ref !== ref)
3992-
)
3993-
(workInProgress.flags |= 512), (workInProgress.flags |= 2097152);
3984+
if (null === ref)
3985+
null !== current &&
3986+
null !== current.ref &&
3987+
(workInProgress.flags |= 2097664);
3988+
else {
3989+
if ("function" !== typeof ref && "object" !== typeof ref)
3990+
throw Error(
3991+
"Expected ref to be a function, an object returned by React.createRef(), or undefined/null."
3992+
);
3993+
if (null === current || current.ref !== ref)
3994+
workInProgress.flags |= 2097664;
3995+
}
39943996
}
39953997
function updateFunctionComponent(
39963998
current,
@@ -9171,7 +9173,7 @@ var devToolsConfig$jscomp$inline_1014 = {
91719173
throw Error("TestRenderer does not support findFiberByHostInstance()");
91729174
},
91739175
bundleType: 0,
9174-
version: "18.3.0-canary-bb4b147da-20240229",
9176+
version: "18.3.0-canary-2f8f77602-20240229",
91759177
rendererPackageName: "react-test-renderer"
91769178
};
91779179
var internals$jscomp$inline_1195 = {
@@ -9202,7 +9204,7 @@ var internals$jscomp$inline_1195 = {
92029204
scheduleRoot: null,
92039205
setRefreshHandler: null,
92049206
getCurrentFiber: null,
9205-
reconcilerVersion: "18.3.0-canary-bb4b147da-20240229"
9207+
reconcilerVersion: "18.3.0-canary-2f8f77602-20240229"
92069208
};
92079209
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
92089210
var hook$jscomp$inline_1196 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js

+22-20
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<86e7f77200b19412957b194553a75177>>
10+
* @generated SignedSource<<749ebcbb693ef8635dc1c79f3b3a628d>>
1111
*/
1212

1313
"use strict";
@@ -1484,24 +1484,19 @@ function convertStringRefToCallbackRef(
14841484
var refs = inst.refs;
14851485
null === value ? delete refs[stringRef] : (refs[stringRef] = value);
14861486
}
1487+
var stringRef = "" + mixedRef;
14871488
returnFiber = element._owner;
1488-
if (!returnFiber) {
1489-
if ("string" !== typeof mixedRef)
1490-
throw Error(
1491-
"Expected ref to be a function, a string, an object returned by React.createRef(), or null."
1492-
);
1489+
if (!returnFiber)
14931490
throw Error(
14941491
"Element ref was specified as a string (" +
1495-
mixedRef +
1492+
stringRef +
14961493
") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://reactjs.org/link/refs-must-have-owner for more information."
14971494
);
1498-
}
14991495
if (1 !== returnFiber.tag)
15001496
throw Error(
15011497
"Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref"
15021498
);
1503-
var stringRef = "" + mixedRef,
1504-
inst = returnFiber.stateNode;
1499+
var inst = returnFiber.stateNode;
15051500
if (!inst)
15061501
throw Error(
15071502
"Missing owner for string ref " +
@@ -1521,9 +1516,9 @@ function convertStringRefToCallbackRef(
15211516
function coerceRef(returnFiber, current, workInProgress, element) {
15221517
var mixedRef = element.ref;
15231518
returnFiber =
1524-
null !== mixedRef &&
1525-
"function" !== typeof mixedRef &&
1526-
"object" !== typeof mixedRef
1519+
"string" === typeof mixedRef ||
1520+
"number" === typeof mixedRef ||
1521+
"boolean" === typeof mixedRef
15271522
? convertStringRefToCallbackRef(returnFiber, current, element, mixedRef)
15281523
: mixedRef;
15291524
workInProgress.ref = returnFiber;
@@ -4068,11 +4063,18 @@ function deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes) {
40684063
}
40694064
function markRef(current, workInProgress) {
40704065
var ref = workInProgress.ref;
4071-
if (
4072-
(null === current && null !== ref) ||
4073-
(null !== current && current.ref !== ref)
4074-
)
4075-
(workInProgress.flags |= 512), (workInProgress.flags |= 2097152);
4066+
if (null === ref)
4067+
null !== current &&
4068+
null !== current.ref &&
4069+
(workInProgress.flags |= 2097664);
4070+
else {
4071+
if ("function" !== typeof ref && "object" !== typeof ref)
4072+
throw Error(
4073+
"Expected ref to be a function, an object returned by React.createRef(), or undefined/null."
4074+
);
4075+
if (null === current || current.ref !== ref)
4076+
workInProgress.flags |= 2097664;
4077+
}
40764078
}
40774079
function updateFunctionComponent(
40784080
current,
@@ -9599,7 +9601,7 @@ var devToolsConfig$jscomp$inline_1056 = {
95999601
throw Error("TestRenderer does not support findFiberByHostInstance()");
96009602
},
96019603
bundleType: 0,
9602-
version: "18.3.0-canary-bb4b147da-20240229",
9604+
version: "18.3.0-canary-2f8f77602-20240229",
96039605
rendererPackageName: "react-test-renderer"
96049606
};
96059607
var internals$jscomp$inline_1236 = {
@@ -9630,7 +9632,7 @@ var internals$jscomp$inline_1236 = {
96309632
scheduleRoot: null,
96319633
setRefreshHandler: null,
96329634
getCurrentFiber: null,
9633-
reconcilerVersion: "18.3.0-canary-bb4b147da-20240229"
9635+
reconcilerVersion: "18.3.0-canary-2f8f77602-20240229"
96349636
};
96359637
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
96369638
var hook$jscomp$inline_1237 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ if (__DEV__) {
2626
}
2727
var dynamicFlags = require("ReactNativeInternalFeatureFlags");
2828

29-
var ReactVersion = "18.3.0-canary-bb4b147da-20240229";
29+
var ReactVersion = "18.3.0-canary-2f8f77602-20240229";
3030

3131
// ATTENTION
3232
// When adding new symbols to this file,

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -598,4 +598,4 @@ exports.useSyncExternalStore = function (
598598
exports.useTransition = function () {
599599
return ReactCurrentDispatcher.current.useTransition();
600600
};
601-
exports.version = "18.3.0-canary-bb4b147da-20240229";
601+
exports.version = "18.3.0-canary-2f8f77602-20240229";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ exports.useSyncExternalStore = function (
594594
exports.useTransition = function () {
595595
return ReactCurrentDispatcher.current.useTransition();
596596
};
597-
exports.version = "18.3.0-canary-bb4b147da-20240229";
597+
exports.version = "18.3.0-canary-2f8f77602-20240229";
598598
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
599599
"function" ===
600600
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bb4b147da9a892529995f55f15f19f46a00cf4f6
1+
2f8f7760223241665f472a2a9be16650473bce39

0 commit comments

Comments
 (0)