Skip to content

Commit

Permalink
Fix checkbox and radio hydration (#27401)
Browse files Browse the repository at this point in the history
Fixes whatever part of #26876
and vercel/next.js#49499 that
#27394 didn't fix, probably.

From manual tests I believe this behavior brings us back to parity with
latest stable release (18.2.0). It's awkward that we keep the user's
state even for controlled inputs, so the DOM is out of sync with React
state.

Previously the .defaultChecked assignment done in updateInput() was
changing the actual checkedness because the dirty flag wasn't getting
set, meaning that hydrating could change which radio button is checked,
even in the absence of user interaction! Now we go back to always
detaching again.

DiffTrain build for [db69f95](db69f95)
  • Loading branch information
sophiebits committed Oct 3, 2023
1 parent fbf7069 commit 3d74031
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 56 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4f4c52a3c8f9c8a2d8133c654841fee257c37249
db69f95e4876ec3c24117f58d55cbb4f315b9fa7
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if (
}
"use strict";

var ReactVersion = "18.3.0-www-classic-ff54ec02";
var ReactVersion = "18.3.0-www-classic-136a3d2d";

// ATTENTION
// When adding new symbols to this file,
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -615,4 +615,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-modern-dc699db3";
exports.version = "18.3.0-www-modern-939a7938";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-modern-622fc29e";
exports.version = "18.3.0-www-modern-de10697a";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
13 changes: 6 additions & 7 deletions compiled/facebook-www/ReactDOM-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4016,13 +4016,12 @@ function initInput(
var initialChecked =
typeof checkedOrDefault !== "function" &&
typeof checkedOrDefault !== "symbol" &&
!!checkedOrDefault; // The checked property never gets assigned. It must be manually set.
// We don't want to do this when hydrating so that existing user input isn't
// modified
// TODO: I'm pretty sure this is a bug because initialValueTracking won't be
// correct for the hydration case then.
!!checkedOrDefault;

if (!isHydrating) {
if (isHydrating) {
// Detach .checked from .defaultChecked but leave user input alone
node.checked = node.checked;
} else {
node.checked = !!initialChecked;
}

Expand Down Expand Up @@ -33977,7 +33976,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-classic-9c42e3d4";
var ReactVersion = "18.3.0-www-classic-85c09bff";

function createPortal$1(
children,
Expand Down
13 changes: 6 additions & 7 deletions compiled/facebook-www/ReactDOM-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -3858,13 +3858,12 @@ function initInput(
var initialChecked =
typeof checkedOrDefault !== "function" &&
typeof checkedOrDefault !== "symbol" &&
!!checkedOrDefault; // The checked property never gets assigned. It must be manually set.
// We don't want to do this when hydrating so that existing user input isn't
// modified
// TODO: I'm pretty sure this is a bug because initialValueTracking won't be
// correct for the hydration case then.
!!checkedOrDefault;

if (!isHydrating) {
if (isHydrating) {
// Detach .checked from .defaultChecked but leave user input alone
node.checked = node.checked;
} else {
node.checked = !!initialChecked;
}

Expand Down Expand Up @@ -33822,7 +33821,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-modern-752f226e";
var ReactVersion = "18.3.0-www-modern-c7df3b44";

function createPortal$1(
children,
Expand Down
8 changes: 4 additions & 4 deletions compiled/facebook-www/ReactDOM-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ function initInput(
}
value = null != checked ? checked : defaultChecked;
value = "function" !== typeof value && "symbol" !== typeof value && !!value;
isHydrating || (element.checked = !!value);
element.checked = isHydrating ? element.checked : !!value;
disableInputAttributeSyncing
? null != defaultChecked && (element.defaultChecked = !!defaultChecked)
: (element.defaultChecked = !!value);
Expand Down Expand Up @@ -16375,7 +16375,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1779 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-4ef77085",
version: "18.3.0-www-classic-a202a369",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2123 = {
Expand Down Expand Up @@ -16405,7 +16405,7 @@ var internals$jscomp$inline_2123 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-4ef77085"
reconcilerVersion: "18.3.0-www-classic-a202a369"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2124 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16742,4 +16742,4 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-classic-4ef77085";
exports.version = "18.3.0-www-classic-a202a369";
8 changes: 4 additions & 4 deletions compiled/facebook-www/ReactDOM-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ function initInput(
}
value = null != checked ? checked : defaultChecked;
value = "function" !== typeof value && "symbol" !== typeof value && !!value;
isHydrating || (element.checked = !!value);
element.checked = isHydrating ? element.checked : !!value;
disableInputAttributeSyncing
? null != defaultChecked && (element.defaultChecked = !!defaultChecked)
: (element.defaultChecked = !!value);
Expand Down Expand Up @@ -15897,7 +15897,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1738 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-7f3360c5",
version: "18.3.0-www-modern-7e008df6",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2087 = {
Expand Down Expand Up @@ -15928,7 +15928,7 @@ var internals$jscomp$inline_2087 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-7f3360c5"
reconcilerVersion: "18.3.0-www-modern-7e008df6"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2088 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16193,4 +16193,4 @@ exports.unstable_createEventHandle = function (type, options) {
return eventHandle;
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-modern-7f3360c5";
exports.version = "18.3.0-www-modern-7e008df6";
8 changes: 4 additions & 4 deletions compiled/facebook-www/ReactDOM-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -1228,7 +1228,7 @@ function initInput(
}
value = null != checked ? checked : defaultChecked;
value = "function" !== typeof value && "symbol" !== typeof value && !!value;
isHydrating || (element.checked = !!value);
element.checked = isHydrating ? element.checked : !!value;
disableInputAttributeSyncing
? null != defaultChecked && (element.defaultChecked = !!defaultChecked)
: (element.defaultChecked = !!value);
Expand Down Expand Up @@ -17150,7 +17150,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1864 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-9802da3a",
version: "18.3.0-www-classic-bf660d13",
rendererPackageName: "react-dom"
};
(function (internals) {
Expand Down Expand Up @@ -17194,7 +17194,7 @@ var devToolsConfig$jscomp$inline_1864 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-9802da3a"
reconcilerVersion: "18.3.0-www-classic-bf660d13"
});
assign(Internals, {
ReactBrowserEventEmitter: {
Expand Down Expand Up @@ -17518,7 +17518,7 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-classic-9802da3a";
exports.version = "18.3.0-www-classic-bf660d13";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
8 changes: 4 additions & 4 deletions compiled/facebook-www/ReactDOM-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,7 @@ function initInput(
}
value = null != checked ? checked : defaultChecked;
value = "function" !== typeof value && "symbol" !== typeof value && !!value;
isHydrating || (element.checked = !!value);
element.checked = isHydrating ? element.checked : !!value;
disableInputAttributeSyncing
? null != defaultChecked && (element.defaultChecked = !!defaultChecked)
: (element.defaultChecked = !!value);
Expand Down Expand Up @@ -16666,7 +16666,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1823 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-ea3ac45f",
version: "18.3.0-www-modern-9d2908e6",
rendererPackageName: "react-dom"
};
(function (internals) {
Expand Down Expand Up @@ -16711,7 +16711,7 @@ var devToolsConfig$jscomp$inline_1823 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-ea3ac45f"
reconcilerVersion: "18.3.0-www-modern-9d2908e6"
});
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
exports.createPortal = function (children, container) {
Expand Down Expand Up @@ -16963,7 +16963,7 @@ exports.unstable_createEventHandle = function (type, options) {
return eventHandle;
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-modern-ea3ac45f";
exports.version = "18.3.0-www-modern-9d2908e6";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
13 changes: 6 additions & 7 deletions compiled/facebook-www/ReactDOMTesting-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4150,13 +4150,12 @@ function initInput(
var initialChecked =
typeof checkedOrDefault !== "function" &&
typeof checkedOrDefault !== "symbol" &&
!!checkedOrDefault; // The checked property never gets assigned. It must be manually set.
// We don't want to do this when hydrating so that existing user input isn't
// modified
// TODO: I'm pretty sure this is a bug because initialValueTracking won't be
// correct for the hydration case then.
!!checkedOrDefault;

if (!isHydrating) {
if (isHydrating) {
// Detach .checked from .defaultChecked but leave user input alone
node.checked = node.checked;
} else {
node.checked = !!initialChecked;
}

Expand Down Expand Up @@ -34594,7 +34593,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-classic-ffc4f8d2";
var ReactVersion = "18.3.0-www-classic-32c273fd";

function createPortal$1(
children,
Expand Down
13 changes: 6 additions & 7 deletions compiled/facebook-www/ReactDOMTesting-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -3992,13 +3992,12 @@ function initInput(
var initialChecked =
typeof checkedOrDefault !== "function" &&
typeof checkedOrDefault !== "symbol" &&
!!checkedOrDefault; // The checked property never gets assigned. It must be manually set.
// We don't want to do this when hydrating so that existing user input isn't
// modified
// TODO: I'm pretty sure this is a bug because initialValueTracking won't be
// correct for the hydration case then.
!!checkedOrDefault;

if (!isHydrating) {
if (isHydrating) {
// Detach .checked from .defaultChecked but leave user input alone
node.checked = node.checked;
} else {
node.checked = !!initialChecked;
}

Expand Down Expand Up @@ -34439,7 +34438,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-modern-dc699db3";
var ReactVersion = "18.3.0-www-modern-939a7938";

function createPortal$1(
children,
Expand Down
8 changes: 4 additions & 4 deletions compiled/facebook-www/ReactDOMTesting-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ function initInput(
}
value = null != checked ? checked : defaultChecked;
value = "function" !== typeof value && "symbol" !== typeof value && !!value;
isHydrating || (element.checked = !!value);
element.checked = isHydrating ? element.checked : !!value;
disableInputAttributeSyncing
? null != defaultChecked && (element.defaultChecked = !!defaultChecked)
: (element.defaultChecked = !!value);
Expand Down Expand Up @@ -16704,7 +16704,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1808 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-ff54ec02",
version: "18.3.0-www-classic-136a3d2d",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2157 = {
Expand Down Expand Up @@ -16734,7 +16734,7 @@ var internals$jscomp$inline_2157 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-ff54ec02"
reconcilerVersion: "18.3.0-www-classic-136a3d2d"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2158 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -17222,4 +17222,4 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-classic-ff54ec02";
exports.version = "18.3.0-www-classic-136a3d2d";
8 changes: 4 additions & 4 deletions compiled/facebook-www/ReactDOMTesting-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ function initInput(
}
value = null != checked ? checked : defaultChecked;
value = "function" !== typeof value && "symbol" !== typeof value && !!value;
isHydrating || (element.checked = !!value);
element.checked = isHydrating ? element.checked : !!value;
disableInputAttributeSyncing
? null != defaultChecked && (element.defaultChecked = !!defaultChecked)
: (element.defaultChecked = !!value);
Expand Down Expand Up @@ -16281,7 +16281,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1767 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-622fc29e",
version: "18.3.0-www-modern-de10697a",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2121 = {
Expand Down Expand Up @@ -16312,7 +16312,7 @@ var internals$jscomp$inline_2121 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-622fc29e"
reconcilerVersion: "18.3.0-www-modern-de10697a"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2122 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16728,4 +16728,4 @@ exports.unstable_createEventHandle = function (type, options) {
return eventHandle;
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-modern-622fc29e";
exports.version = "18.3.0-www-modern-de10697a";

0 comments on commit 3d74031

Please sign in to comment.