Skip to content

Commit e0a3dc5

Browse files
committed
[compiler] disallow ref access in state initializer, reducer/initializer (#34025)
Per title, disallow ref access in `useState()` initializer function, `useReducer()` reducer, and `useReducer()` init function. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34025). * #34027 * #34026 * __->__ #34025 DiffTrain build for [c2326b1](c2326b1)
1 parent 7f88cd0 commit e0a3dc5

35 files changed

+102
-95
lines changed

compiled/eslint-plugin-react-hooks/index.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48350,9 +48350,10 @@ function validateNoRefAccessInRenderImpl(fn, env) {
4835048350
for (let i = 0; (i == 0 || env.hasChanged()) && i < 10; i++) {
4835148351
env.resetChanged();
4835248352
returnValues = [];
48353-
const safeBlocks = new Map();
48353+
const safeBlocks = [];
4835448354
const errors = new CompilerError();
4835548355
for (const [, block] of fn.body.blocks) {
48356+
retainWhere(safeBlocks, entry => entry.block !== block.id);
4835648357
for (const phi of block.phis) {
4835748358
env.set(phi.place.identifier.id, joinRefAccessTypes(...Array(...phi.operands.values()).map(operand => { var _a; return (_a = env.get(operand.identifier.id)) !== null && _a !== void 0 ? _a : { kind: 'None' }; })));
4835848359
}
@@ -48460,7 +48461,10 @@ function validateNoRefAccessInRenderImpl(fn, env) {
4846048461
if (!didError) {
4846148462
const isRefLValue = isUseRefType(instr.lvalue.identifier);
4846248463
for (const operand of eachInstructionValueOperand(instr.value)) {
48463-
if (isRefLValue || hookKind != null) {
48464+
if (isRefLValue ||
48465+
(hookKind != null &&
48466+
hookKind !== 'useState' &&
48467+
hookKind !== 'useReducer')) {
4846448468
validateNoDirectRefValueAccess(errors, operand, env);
4846548469
}
4846648470
else if (interpolatedAsJsx.has(instr.lvalue.identifier.id)) {
@@ -48500,13 +48504,15 @@ function validateNoRefAccessInRenderImpl(fn, env) {
4850048504
case 'PropertyStore':
4850148505
case 'ComputedDelete':
4850248506
case 'ComputedStore': {
48503-
const safe = safeBlocks.get(block.id);
4850448507
const target = env.get(instr.value.object.identifier.id);
48508+
let safe = null;
4850548509
if (instr.value.kind === 'PropertyStore' &&
48506-
safe != null &&
48507-
(target === null || target === void 0 ? void 0 : target.kind) === 'Ref' &&
48508-
target.refId === safe) {
48509-
safeBlocks.delete(block.id);
48510+
target != null &&
48511+
target.kind === 'Ref') {
48512+
safe = safeBlocks.find(entry => entry.ref === target.refId);
48513+
}
48514+
if (safe != null) {
48515+
retainWhere(safeBlocks, entry => entry !== safe);
4851048516
}
4851148517
else {
4851248518
validateNoRefUpdate(errors, env, instr.value.object, instr.loc);
@@ -48576,8 +48582,9 @@ function validateNoRefAccessInRenderImpl(fn, env) {
4857648582
}
4857748583
if (block.terminal.kind === 'if') {
4857848584
const test = env.get(block.terminal.test.identifier.id);
48579-
if ((test === null || test === void 0 ? void 0 : test.kind) === 'Guard') {
48580-
safeBlocks.set(block.terminal.consequent, test.refId);
48585+
if ((test === null || test === void 0 ? void 0 : test.kind) === 'Guard' &&
48586+
safeBlocks.find(entry => entry.ref === test.refId) == null) {
48587+
safeBlocks.push({ block: block.terminal.fallthrough, ref: test.refId });
4858148588
}
4858248589
}
4858348590
for (const operand of eachTerminalOperand(block.terminal)) {

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6891dcb87db831db17ab109730dea63706875dd7
1+
c2326b1336e38a52899fad6c2ddbb71ea7ddd3ee
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6891dcb87db831db17ab109730dea63706875dd7
1+
c2326b1336e38a52899fad6c2ddbb71ea7ddd3ee

compiled/facebook-www/React-dev.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ __DEV__ &&
14341434
exports.useTransition = function () {
14351435
return resolveDispatcher().useTransition();
14361436
};
1437-
exports.version = "19.2.0-www-classic-6891dcb8-20250729";
1437+
exports.version = "19.2.0-www-classic-c2326b13-20250729";
14381438
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14391439
"function" ===
14401440
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ __DEV__ &&
14341434
exports.useTransition = function () {
14351435
return resolveDispatcher().useTransition();
14361436
};
1437-
exports.version = "19.2.0-www-modern-6891dcb8-20250729";
1437+
exports.version = "19.2.0-www-modern-c2326b13-20250729";
14381438
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14391439
"function" ===
14401440
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-prod.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,4 +610,4 @@ exports.useSyncExternalStore = function (
610610
exports.useTransition = function () {
611611
return ReactSharedInternals.H.useTransition();
612612
};
613-
exports.version = "19.2.0-www-classic-6891dcb8-20250729";
613+
exports.version = "19.2.0-www-classic-c2326b13-20250729";

compiled/facebook-www/React-prod.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,4 +610,4 @@ exports.useSyncExternalStore = function (
610610
exports.useTransition = function () {
611611
return ReactSharedInternals.H.useTransition();
612612
};
613-
exports.version = "19.2.0-www-modern-6891dcb8-20250729";
613+
exports.version = "19.2.0-www-modern-c2326b13-20250729";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ exports.useSyncExternalStore = function (
614614
exports.useTransition = function () {
615615
return ReactSharedInternals.H.useTransition();
616616
};
617-
exports.version = "19.2.0-www-classic-6891dcb8-20250729";
617+
exports.version = "19.2.0-www-classic-c2326b13-20250729";
618618
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
619619
"function" ===
620620
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-profiling.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ exports.useSyncExternalStore = function (
614614
exports.useTransition = function () {
615615
return ReactSharedInternals.H.useTransition();
616616
};
617-
exports.version = "19.2.0-www-modern-6891dcb8-20250729";
617+
exports.version = "19.2.0-www-modern-c2326b13-20250729";
618618
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
619619
"function" ===
620620
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/ReactART-dev.classic.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19318,10 +19318,10 @@ __DEV__ &&
1931819318
(function () {
1931919319
var internals = {
1932019320
bundleType: 1,
19321-
version: "19.2.0-www-classic-6891dcb8-20250729",
19321+
version: "19.2.0-www-classic-c2326b13-20250729",
1932219322
rendererPackageName: "react-art",
1932319323
currentDispatcherRef: ReactSharedInternals,
19324-
reconcilerVersion: "19.2.0-www-classic-6891dcb8-20250729"
19324+
reconcilerVersion: "19.2.0-www-classic-c2326b13-20250729"
1932519325
};
1932619326
internals.overrideHookState = overrideHookState;
1932719327
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -19355,7 +19355,7 @@ __DEV__ &&
1935519355
exports.Shape = Shape;
1935619356
exports.Surface = Surface;
1935719357
exports.Text = Text;
19358-
exports.version = "19.2.0-www-classic-6891dcb8-20250729";
19358+
exports.version = "19.2.0-www-classic-c2326b13-20250729";
1935919359
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1936019360
"function" ===
1936119361
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)