Skip to content

Commit ddedc1e

Browse files
committed
[DevTools] Stop mounting empty roots (facebook#34467)
DiffTrain build for [a9ad64c](facebook@a9ad64c)
1 parent 66d2ab0 commit ddedc1e

35 files changed

+153
-90
lines changed

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

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32144,6 +32144,7 @@ const EnvironmentConfigSchema = zod.z.object({
3214432144
lowerContextAccess: ExternalFunctionSchema.nullable().default(null),
3214532145
validateNoVoidUseMemo: zod.z.boolean().default(false),
3214632146
validateNoDynamicallyCreatedComponentsOrHooks: zod.z.boolean().default(false),
32147+
enableAllowSetStateFromRefsInEffects: zod.z.boolean().default(true),
3214732148
});
3214832149
class Environment {
3214932150
constructor(scope, fnType, compilerMode, config, contextIdentifiers, parentFunction, logger, filename, code, programContext) {
@@ -49447,12 +49448,46 @@ function validateNoRefAccessInRenderImpl(fn, env) {
4944749448
case 'StartMemoize':
4944849449
case 'FinishMemoize':
4944949450
break;
49451+
case 'LoadGlobal': {
49452+
if (instr.value.binding.name === 'undefined') {
49453+
env.set(instr.lvalue.identifier.id, { kind: 'Nullable' });
49454+
}
49455+
break;
49456+
}
4945049457
case 'Primitive': {
4945149458
if (instr.value.value == null) {
4945249459
env.set(instr.lvalue.identifier.id, { kind: 'Nullable' });
4945349460
}
4945449461
break;
4945549462
}
49463+
case 'UnaryExpression': {
49464+
if (instr.value.operator === '!') {
49465+
const value = env.get(instr.value.value.identifier.id);
49466+
const refId = (value === null || value === void 0 ? void 0 : value.kind) === 'RefValue' && value.refId != null
49467+
? value.refId
49468+
: null;
49469+
if (refId !== null) {
49470+
env.set(instr.lvalue.identifier.id, { kind: 'Guard', refId });
49471+
errors.pushDiagnostic(CompilerDiagnostic.create({
49472+
category: ErrorCategory.Refs,
49473+
reason: 'Cannot access refs during render',
49474+
description: ERROR_DESCRIPTION,
49475+
})
49476+
.withDetails({
49477+
kind: 'error',
49478+
loc: instr.value.value.loc,
49479+
message: `Cannot access ref value during render`,
49480+
})
49481+
.withDetails({
49482+
kind: 'hint',
49483+
message: 'To initialize a ref only once, check that the ref is null with the pattern `if (ref.current == null) { ref.current = ... }`',
49484+
}));
49485+
break;
49486+
}
49487+
}
49488+
validateNoRefValueAccess(errors, env, instr.value.value);
49489+
break;
49490+
}
4945649491
case 'BinaryExpression': {
4945749492
const left = env.get(instr.value.left.identifier.id);
4945849493
const right = env.get(instr.value.right.identifier.id);
@@ -50579,7 +50614,7 @@ function emitArrayInstr(elements, env) {
5057950614
return arrayInstr;
5058050615
}
5058150616

50582-
function validateNoSetStateInEffects(fn) {
50617+
function validateNoSetStateInEffects(fn, env) {
5058350618
const setStateFunctions = new Map();
5058450619
const errors = new CompilerError();
5058550620
for (const [, block] of fn.body.blocks) {
@@ -50601,7 +50636,7 @@ function validateNoSetStateInEffects(fn) {
5060150636
case 'FunctionExpression': {
5060250637
if ([...eachInstructionValueOperand(instr.value)].some(operand => isSetStateType(operand.identifier) ||
5060350638
setStateFunctions.has(operand.identifier.id))) {
50604-
const callee = getSetStateCall(instr.value.loweredFunc.func, setStateFunctions);
50639+
const callee = getSetStateCall(instr.value.loweredFunc.func, setStateFunctions, env);
5060550640
if (callee !== null) {
5060650641
setStateFunctions.set(instr.lvalue.identifier.id, callee);
5060750642
}
@@ -50645,9 +50680,29 @@ function validateNoSetStateInEffects(fn) {
5064550680
}
5064650681
return errors.asResult();
5064750682
}
50648-
function getSetStateCall(fn, setStateFunctions) {
50683+
function getSetStateCall(fn, setStateFunctions, env) {
50684+
const refDerivedValues = new Set();
50685+
const isDerivedFromRef = (place) => {
50686+
return (refDerivedValues.has(place.identifier.id) ||
50687+
isUseRefType(place.identifier) ||
50688+
isRefValueType(place.identifier));
50689+
};
5064950690
for (const [, block] of fn.body.blocks) {
5065050691
for (const instr of block.instructions) {
50692+
if (env.config.enableAllowSetStateFromRefsInEffects) {
50693+
const hasRefOperand = Iterable_some(eachInstructionValueOperand(instr.value), isDerivedFromRef);
50694+
if (hasRefOperand) {
50695+
for (const lvalue of eachInstructionLValue(instr)) {
50696+
refDerivedValues.add(lvalue.identifier.id);
50697+
}
50698+
}
50699+
if (instr.value.kind === 'PropertyLoad' &&
50700+
instr.value.property === 'current' &&
50701+
(isUseRefType(instr.value.object.identifier) ||
50702+
isRefValueType(instr.value.object.identifier))) {
50703+
refDerivedValues.add(instr.lvalue.identifier.id);
50704+
}
50705+
}
5065150706
switch (instr.value.kind) {
5065250707
case 'LoadLocal': {
5065350708
if (setStateFunctions.has(instr.value.place.identifier.id)) {
@@ -50666,6 +50721,14 @@ function getSetStateCall(fn, setStateFunctions) {
5066650721
const callee = instr.value.callee;
5066750722
if (isSetStateType(callee.identifier) ||
5066850723
setStateFunctions.has(callee.identifier.id)) {
50724+
if (env.config.enableAllowSetStateFromRefsInEffects) {
50725+
const arg = instr.value.args.at(0);
50726+
if (arg !== undefined &&
50727+
arg.kind === 'Identifier' &&
50728+
refDerivedValues.has(arg.identifier.id)) {
50729+
return null;
50730+
}
50731+
}
5066950732
return callee;
5067050733
}
5067150734
}
@@ -52129,7 +52192,7 @@ function runWithEnvironment(func, env) {
5212952192
validateNoDerivedComputationsInEffects(hir);
5213052193
}
5213152194
if (env.config.validateNoSetStateInEffects) {
52132-
env.logErrors(validateNoSetStateInEffects(hir));
52195+
env.logErrors(validateNoSetStateInEffects(hir, env));
5213352196
}
5213452197
if (env.config.validateNoJSXInTryStatements) {
5213552198
env.logErrors(validateNoJSXInTryStatement(hir));

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
e2ba45bb39bd744454ee599bdc2df497c79d9707
1+
a9ad64c8524eb7a9af6753baa715a41909552fa6
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
e2ba45bb39bd744454ee599bdc2df497c79d9707
1+
a9ad64c8524eb7a9af6753baa715a41909552fa6

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ __DEV__ &&
14181418
exports.useTransition = function () {
14191419
return resolveDispatcher().useTransition();
14201420
};
1421-
exports.version = "19.2.0-www-classic-e2ba45bb-20250910";
1421+
exports.version = "19.2.0-www-classic-a9ad64c8-20250911";
14221422
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14231423
"function" ===
14241424
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
@@ -1418,7 +1418,7 @@ __DEV__ &&
14181418
exports.useTransition = function () {
14191419
return resolveDispatcher().useTransition();
14201420
};
1421-
exports.version = "19.2.0-www-modern-e2ba45bb-20250910";
1421+
exports.version = "19.2.0-www-modern-a9ad64c8-20250911";
14221422
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14231423
"function" ===
14241424
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
@@ -600,4 +600,4 @@ exports.useSyncExternalStore = function (
600600
exports.useTransition = function () {
601601
return ReactSharedInternals.H.useTransition();
602602
};
603-
exports.version = "19.2.0-www-classic-e2ba45bb-20250910";
603+
exports.version = "19.2.0-www-classic-a9ad64c8-20250911";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,4 +600,4 @@ exports.useSyncExternalStore = function (
600600
exports.useTransition = function () {
601601
return ReactSharedInternals.H.useTransition();
602602
};
603-
exports.version = "19.2.0-www-modern-e2ba45bb-20250910";
603+
exports.version = "19.2.0-www-modern-a9ad64c8-20250911";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ exports.useSyncExternalStore = function (
604604
exports.useTransition = function () {
605605
return ReactSharedInternals.H.useTransition();
606606
};
607-
exports.version = "19.2.0-www-classic-e2ba45bb-20250910";
607+
exports.version = "19.2.0-www-classic-a9ad64c8-20250911";
608608
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
609609
"function" ===
610610
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
@@ -604,7 +604,7 @@ exports.useSyncExternalStore = function (
604604
exports.useTransition = function () {
605605
return ReactSharedInternals.H.useTransition();
606606
};
607-
exports.version = "19.2.0-www-modern-e2ba45bb-20250910";
607+
exports.version = "19.2.0-www-modern-a9ad64c8-20250911";
608608
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
609609
"function" ===
610610
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
@@ -19708,10 +19708,10 @@ __DEV__ &&
1970819708
(function () {
1970919709
var internals = {
1971019710
bundleType: 1,
19711-
version: "19.2.0-www-classic-e2ba45bb-20250910",
19711+
version: "19.2.0-www-classic-a9ad64c8-20250911",
1971219712
rendererPackageName: "react-art",
1971319713
currentDispatcherRef: ReactSharedInternals,
19714-
reconcilerVersion: "19.2.0-www-classic-e2ba45bb-20250910"
19714+
reconcilerVersion: "19.2.0-www-classic-a9ad64c8-20250911"
1971519715
};
1971619716
internals.overrideHookState = overrideHookState;
1971719717
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -19745,7 +19745,7 @@ __DEV__ &&
1974519745
exports.Shape = Shape;
1974619746
exports.Surface = Surface;
1974719747
exports.Text = Text;
19748-
exports.version = "19.2.0-www-classic-e2ba45bb-20250910";
19748+
exports.version = "19.2.0-www-classic-a9ad64c8-20250911";
1974919749
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1975019750
"function" ===
1975119751
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)