Skip to content

Commit

Permalink
Move ref type check to receiver (#28464)
Browse files Browse the repository at this point in the history
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 [2f8f776](2f8f776)
  • Loading branch information
acdlite committed Mar 1, 2024
1 parent df4b99c commit 6e4aad3
Show file tree
Hide file tree
Showing 19 changed files with 369 additions and 369 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bb4b147da9a892529995f55f15f19f46a00cf4f6
2f8f7760223241665f472a2a9be16650473bce39
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -633,4 +633,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-classic-46c2f9a3";
exports.version = "18.3.0-www-classic-d9a6038e";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-classic-4f385f77";
exports.version = "18.3.0-www-classic-cf792bcf";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
56 changes: 27 additions & 29 deletions compiled/facebook-www/ReactART-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ if (__DEV__) {
return self;
}

var ReactVersion = "18.3.0-www-classic-f1606359";
var ReactVersion = "18.3.0-www-classic-2abfd3d0";

var LegacyRoot = 0;
var ConcurrentRoot = 1;
Expand Down Expand Up @@ -6381,18 +6381,17 @@ if (__DEV__) {
element,
mixedRef
) {
{
checkPropStringCoercion(mixedRef, "ref");
}

var stringRef = "" + mixedRef;
var owner = element._owner;

if (!owner) {
if (typeof mixedRef !== "string") {
throw new Error(
"Expected ref to be a function, a string, an object returned by React.createRef(), or null."
);
}

throw new Error(
"Element ref was specified as a string (" +
mixedRef +
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" +
Expand All @@ -6409,15 +6408,8 @@ if (__DEV__) {
"Learn more about using refs safely here: " +
"https://reactjs.org/link/strict-mode-string-ref"
);
} // At this point, we know the ref isn't an object or function but it could
// be a number. Coerce it to a string.

{
checkPropStringCoercion(mixedRef, "ref");
}

var stringRef = "" + mixedRef;

{
if (
// Will already warn with "Function components cannot be given refs"
Expand Down Expand Up @@ -6495,12 +6487,10 @@ if (__DEV__) {
var coercedRef;

if (
mixedRef !== null &&
typeof mixedRef !== "function" &&
typeof mixedRef !== "object"
typeof mixedRef === "string" ||
typeof mixedRef === "number" ||
typeof mixedRef === "boolean"
) {
// Assume this is a string ref. If it's not, then this will throw an error
// to the user.
coercedRef = convertStringRefToCallbackRef(
returnFiber,
current,
Expand Down Expand Up @@ -15337,17 +15327,25 @@ if (__DEV__) {
}

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

if (
(current === null && ref !== null) ||
(current !== null && current.ref !== ref)
) {
// Schedule a Ref effect
workInProgress.flags |= Ref;
workInProgress.flags |= RefStatic;
if (ref === null) {
if (current !== null && current.ref !== null) {
// Schedule a Ref effect
workInProgress.flags |= Ref | RefStatic;
}
} else {
if (typeof ref !== "function" && typeof ref !== "object") {
throw new Error(
"Expected ref to be a function, an object returned by React.createRef(), or undefined/null."
);
}

if (current === null || current.ref !== ref) {
// Schedule a Ref effect
workInProgress.flags |= Ref | RefStatic;
}
}
}

Expand Down
56 changes: 27 additions & 29 deletions compiled/facebook-www/ReactART-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ if (__DEV__) {
return self;
}

var ReactVersion = "18.3.0-www-modern-0bd008ad";
var ReactVersion = "18.3.0-www-modern-62d2932f";

var LegacyRoot = 0;
var ConcurrentRoot = 1;
Expand Down Expand Up @@ -6146,18 +6146,17 @@ if (__DEV__) {
element,
mixedRef
) {
{
checkPropStringCoercion(mixedRef, "ref");
}

var stringRef = "" + mixedRef;
var owner = element._owner;

if (!owner) {
if (typeof mixedRef !== "string") {
throw new Error(
"Expected ref to be a function, a string, an object returned by React.createRef(), or null."
);
}

throw new Error(
"Element ref was specified as a string (" +
mixedRef +
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" +
Expand All @@ -6174,15 +6173,8 @@ if (__DEV__) {
"Learn more about using refs safely here: " +
"https://reactjs.org/link/strict-mode-string-ref"
);
} // At this point, we know the ref isn't an object or function but it could
// be a number. Coerce it to a string.

{
checkPropStringCoercion(mixedRef, "ref");
}

var stringRef = "" + mixedRef;

{
if (
// Will already warn with "Function components cannot be given refs"
Expand Down Expand Up @@ -6260,12 +6252,10 @@ if (__DEV__) {
var coercedRef;

if (
mixedRef !== null &&
typeof mixedRef !== "function" &&
typeof mixedRef !== "object"
typeof mixedRef === "string" ||
typeof mixedRef === "number" ||
typeof mixedRef === "boolean"
) {
// Assume this is a string ref. If it's not, then this will throw an error
// to the user.
coercedRef = convertStringRefToCallbackRef(
returnFiber,
current,
Expand Down Expand Up @@ -15061,17 +15051,25 @@ if (__DEV__) {
}

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

if (
(current === null && ref !== null) ||
(current !== null && current.ref !== ref)
) {
// Schedule a Ref effect
workInProgress.flags |= Ref;
workInProgress.flags |= RefStatic;
if (ref === null) {
if (current !== null && current.ref !== null) {
// Schedule a Ref effect
workInProgress.flags |= Ref | RefStatic;
}
} else {
if (typeof ref !== "function" && typeof ref !== "object") {
throw new Error(
"Expected ref to be a function, an object returned by React.createRef(), or undefined/null."
);
}

if (current === null || current.ref !== ref) {
// Schedule a Ref effect
workInProgress.flags |= Ref | RefStatic;
}
}
}

Expand Down
34 changes: 18 additions & 16 deletions compiled/facebook-www/ReactART-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -1845,14 +1845,11 @@ function convertStringRefToCallbackRef(
var refs = inst.refs;
null === value ? delete refs[stringRef] : (refs[stringRef] = value);
}
var stringRef = "" + mixedRef;
returnFiber = element._owner;
if (!returnFiber) {
if ("string" !== typeof mixedRef) throw Error(formatProdErrorMessage(284));
throw Error(formatProdErrorMessage(290, mixedRef));
}
if (!returnFiber) throw Error(formatProdErrorMessage(290, stringRef));
if (1 !== returnFiber.tag) throw Error(formatProdErrorMessage(309));
var stringRef = "" + mixedRef,
inst = returnFiber.stateNode;
var inst = returnFiber.stateNode;
if (!inst) throw Error(formatProdErrorMessage(147, stringRef));
if (
null !== current &&
Expand All @@ -1869,9 +1866,9 @@ function coerceRef(returnFiber, current, workInProgress, element) {
var mixedRef = element.props.ref;
mixedRef = void 0 !== mixedRef ? mixedRef : null;
} else mixedRef = element.ref;
null !== mixedRef &&
"function" !== typeof mixedRef &&
"object" !== typeof mixedRef
"string" === typeof mixedRef ||
"number" === typeof mixedRef ||
"boolean" === typeof mixedRef
? ((returnFiber = convertStringRefToCallbackRef(
returnFiber,
current,
Expand Down Expand Up @@ -4599,11 +4596,16 @@ function deferHiddenOffscreenComponent(
}
function markRef(current, workInProgress) {
var ref = workInProgress.ref;
if (
(null === current && null !== ref) ||
(null !== current && current.ref !== ref)
)
(workInProgress.flags |= 512), (workInProgress.flags |= 2097152);
if (null === ref)
null !== current &&
null !== current.ref &&
(workInProgress.flags |= 2097664);
else {
if ("function" !== typeof ref && "object" !== typeof ref)
throw Error(formatProdErrorMessage(284));
if (null === current || current.ref !== ref)
workInProgress.flags |= 2097664;
}
}
function updateFunctionComponent(
current,
Expand Down Expand Up @@ -10594,7 +10596,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "18.3.0-www-classic-36516bcc",
version: "18.3.0-www-classic-0f4883c5",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1320 = {
Expand Down Expand Up @@ -10625,7 +10627,7 @@ var internals$jscomp$inline_1320 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-36516bcc"
reconcilerVersion: "18.3.0-www-classic-0f4883c5"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1321 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
34 changes: 18 additions & 16 deletions compiled/facebook-www/ReactART-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -1641,14 +1641,11 @@ function convertStringRefToCallbackRef(
var refs = inst.refs;
null === value ? delete refs[stringRef] : (refs[stringRef] = value);
}
var stringRef = "" + mixedRef;
returnFiber = element._owner;
if (!returnFiber) {
if ("string" !== typeof mixedRef) throw Error(formatProdErrorMessage(284));
throw Error(formatProdErrorMessage(290, mixedRef));
}
if (!returnFiber) throw Error(formatProdErrorMessage(290, stringRef));
if (1 !== returnFiber.tag) throw Error(formatProdErrorMessage(309));
var stringRef = "" + mixedRef,
inst = returnFiber.stateNode;
var inst = returnFiber.stateNode;
if (!inst) throw Error(formatProdErrorMessage(147, stringRef));
if (
null !== current &&
Expand All @@ -1665,9 +1662,9 @@ function coerceRef(returnFiber, current, workInProgress, element) {
var mixedRef = element.props.ref;
mixedRef = void 0 !== mixedRef ? mixedRef : null;
} else mixedRef = element.ref;
null !== mixedRef &&
"function" !== typeof mixedRef &&
"object" !== typeof mixedRef
"string" === typeof mixedRef ||
"number" === typeof mixedRef ||
"boolean" === typeof mixedRef
? ((returnFiber = convertStringRefToCallbackRef(
returnFiber,
current,
Expand Down Expand Up @@ -4380,11 +4377,16 @@ function deferHiddenOffscreenComponent(
}
function markRef(current, workInProgress) {
var ref = workInProgress.ref;
if (
(null === current && null !== ref) ||
(null !== current && current.ref !== ref)
)
(workInProgress.flags |= 512), (workInProgress.flags |= 2097152);
if (null === ref)
null !== current &&
null !== current.ref &&
(workInProgress.flags |= 2097664);
else {
if ("function" !== typeof ref && "object" !== typeof ref)
throw Error(formatProdErrorMessage(284));
if (null === current || current.ref !== ref)
workInProgress.flags |= 2097664;
}
}
function updateFunctionComponent(
current,
Expand Down Expand Up @@ -10249,7 +10251,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "18.3.0-www-modern-630a2790",
version: "18.3.0-www-modern-1b51d894",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1300 = {
Expand Down Expand Up @@ -10280,7 +10282,7 @@ var internals$jscomp$inline_1300 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-630a2790"
reconcilerVersion: "18.3.0-www-modern-1b51d894"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1301 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Loading

0 comments on commit 6e4aad3

Please sign in to comment.