Skip to content

Commit d763d10

Browse files
committed
useDeferredValue has higher priority than partial hydration (#27550)
By default, partial hydration is given the lowest possible priority, because until a tree is updated, the server-rendered HTML is assumed to match the final resolved HTML. However, this isn't completely true because a component may choose to "upgrade" itself upon hydration. The simplest example is a component that calls setState in a useEffect to switch to a richer implementation of the UI. Another example is a component that doesn't have a server- rendered implementation, so it intentionally suspends to force a client- only render. useDeferredValue is an example, too: the server only renders the first pass (the initialValue) argument, and relies on the client to upgrade to the final value. What we should really do in these cases is emit some information into the Fizz stream so that Fiber knows to prioritize the hydration of certain trees. We plan to add a mechanism for this in the future. In the meantime, though, we can at least ensure that the priority of the upgrade task is correct once it's "discovered" during hydration. In this case, the priority of the task spawned by useDeferredValue should have Transition priority, not Offscreen priority. DiffTrain build for commit 779d593.
1 parent faf027a commit d763d10

File tree

13 files changed

+120
-81
lines changed

13 files changed

+120
-81
lines changed

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<4d9878b267a005902b63980f6c367201>>
10+
* @generated SignedSource<<4aba8405b48af51650328aaea1ae0e6d>>
1111
*/
1212

1313
'use strict';
@@ -1693,8 +1693,10 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {
16931693
root.entangledLanes |= spawnedLane;
16941694
root.entanglements[spawnedLaneIndex] |=
16951695
DeferredLane | // If the parent render task suspended, we must also entangle those lanes
1696-
// with the spawned task.
1697-
entangledLanes;
1696+
// with the spawned task, so that the deferred task includes all the same
1697+
// updates that the parent task did. We can exclude any lane that is not
1698+
// used for updates (e.g. Offscreen).
1699+
(entangledLanes & UpdateLanes);
16981700
}
16991701

17001702
function markRootEntangled(root, entangledLanes) {
@@ -21021,13 +21023,20 @@ function requestDeferredLane() {
2102121023
// If there are multiple useDeferredValue hooks in the same render, the
2102221024
// tasks that they spawn should all be batched together, so they should all
2102321025
// receive the same lane.
21024-
if (includesSomeLane(workInProgressRootRenderLanes, OffscreenLane)) {
21026+
// Check the priority of the current render to decide the priority of the
21027+
// deferred task.
21028+
// OffscreenLane is used for prerendering, but we also use OffscreenLane
21029+
// for incremental hydration. It's given the lowest priority because the
21030+
// initial HTML is the same as the final UI. But useDeferredValue during
21031+
// hydration is an exception — we need to upgrade the UI to the final
21032+
// value. So if we're currently hydrating, we treat it like a transition.
21033+
var isPrerendering =
21034+
includesSomeLane(workInProgressRootRenderLanes, OffscreenLane) &&
21035+
!getIsHydrating();
21036+
21037+
if (isPrerendering) {
2102521038
// There's only one OffscreenLane, so if it contains deferred work, we
2102621039
// should just reschedule using the same lane.
21027-
// TODO: We also use OffscreenLane for hydration, on the basis that the
21028-
// initial HTML is the same as the hydrated UI, but since the deferred
21029-
// task will change the UI, it should be treated like an update. Use
21030-
// TransitionHydrationLane to trigger selective hydration.
2103121040
workInProgressDeferredLane = OffscreenLane;
2103221041
} else {
2103321042
// Everything else is spawned as a transition.
@@ -24878,7 +24887,7 @@ function createFiberRoot(
2487824887
return root;
2487924888
}
2488024889

24881-
var ReactVersion = "18.3.0-canary-6db7f4209-20231021";
24890+
var ReactVersion = "18.3.0-canary-779d59374-20231023";
2488224891

2488324892
// Might add PROFILE later.
2488424893

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

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<ed6d8869c24db97c9d90eec277215874>>
10+
* @generated SignedSource<<af98f481db9b1e6f45f4f7d9c8ec7113>>
1111
*/
1212

1313
"use strict";
@@ -485,7 +485,9 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {
485485
var spawnedLaneIndex = 31 - clz32(spawnedLane);
486486
root.entangledLanes |= spawnedLane;
487487
root.entanglements[spawnedLaneIndex] =
488-
root.entanglements[spawnedLaneIndex] | 1073741824 | entangledLanes;
488+
root.entanglements[spawnedLaneIndex] |
489+
1073741824 |
490+
(entangledLanes & 4194218);
489491
}
490492
function markRootEntangled(root, entangledLanes) {
491493
var rootEntangledLanes = (root.entangledLanes |= entangledLanes);
@@ -9017,19 +9019,19 @@ function wrapFiber(fiber) {
90179019
fiberToWrapper.set(fiber, wrapper));
90189020
return wrapper;
90199021
}
9020-
var devToolsConfig$jscomp$inline_1031 = {
9022+
var devToolsConfig$jscomp$inline_1032 = {
90219023
findFiberByHostInstance: function () {
90229024
throw Error("TestRenderer does not support findFiberByHostInstance()");
90239025
},
90249026
bundleType: 0,
9025-
version: "18.3.0-canary-6db7f4209-20231021",
9027+
version: "18.3.0-canary-779d59374-20231023",
90269028
rendererPackageName: "react-test-renderer"
90279029
};
9028-
var internals$jscomp$inline_1224 = {
9029-
bundleType: devToolsConfig$jscomp$inline_1031.bundleType,
9030-
version: devToolsConfig$jscomp$inline_1031.version,
9031-
rendererPackageName: devToolsConfig$jscomp$inline_1031.rendererPackageName,
9032-
rendererConfig: devToolsConfig$jscomp$inline_1031.rendererConfig,
9030+
var internals$jscomp$inline_1225 = {
9031+
bundleType: devToolsConfig$jscomp$inline_1032.bundleType,
9032+
version: devToolsConfig$jscomp$inline_1032.version,
9033+
rendererPackageName: devToolsConfig$jscomp$inline_1032.rendererPackageName,
9034+
rendererConfig: devToolsConfig$jscomp$inline_1032.rendererConfig,
90339035
overrideHookState: null,
90349036
overrideHookStateDeletePath: null,
90359037
overrideHookStateRenamePath: null,
@@ -9046,26 +9048,26 @@ var internals$jscomp$inline_1224 = {
90469048
return null === fiber ? null : fiber.stateNode;
90479049
},
90489050
findFiberByHostInstance:
9049-
devToolsConfig$jscomp$inline_1031.findFiberByHostInstance ||
9051+
devToolsConfig$jscomp$inline_1032.findFiberByHostInstance ||
90509052
emptyFindFiberByHostInstance,
90519053
findHostInstancesForRefresh: null,
90529054
scheduleRefresh: null,
90539055
scheduleRoot: null,
90549056
setRefreshHandler: null,
90559057
getCurrentFiber: null,
9056-
reconcilerVersion: "18.3.0-canary-6db7f4209-20231021"
9058+
reconcilerVersion: "18.3.0-canary-779d59374-20231023"
90579059
};
90589060
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
9059-
var hook$jscomp$inline_1225 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9061+
var hook$jscomp$inline_1226 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
90609062
if (
9061-
!hook$jscomp$inline_1225.isDisabled &&
9062-
hook$jscomp$inline_1225.supportsFiber
9063+
!hook$jscomp$inline_1226.isDisabled &&
9064+
hook$jscomp$inline_1226.supportsFiber
90639065
)
90649066
try {
9065-
(rendererID = hook$jscomp$inline_1225.inject(
9066-
internals$jscomp$inline_1224
9067+
(rendererID = hook$jscomp$inline_1226.inject(
9068+
internals$jscomp$inline_1225
90679069
)),
9068-
(injectedHook = hook$jscomp$inline_1225);
9070+
(injectedHook = hook$jscomp$inline_1226);
90699071
} catch (err) {}
90709072
}
90719073
exports._Scheduler = Scheduler;

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

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<c3d1140631a9ffbb19f029e3ecdb90fc>>
10+
* @generated SignedSource<<55d6fdb51293e0bfc3d0f87e833cd9af>>
1111
*/
1212

1313
"use strict";
@@ -503,7 +503,9 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {
503503
var spawnedLaneIndex = 31 - clz32(spawnedLane);
504504
root.entangledLanes |= spawnedLane;
505505
root.entanglements[spawnedLaneIndex] =
506-
root.entanglements[spawnedLaneIndex] | 1073741824 | entangledLanes;
506+
root.entanglements[spawnedLaneIndex] |
507+
1073741824 |
508+
(entangledLanes & 4194218);
507509
}
508510
function markRootEntangled(root, entangledLanes) {
509511
var rootEntangledLanes = (root.entangledLanes |= entangledLanes);
@@ -9443,19 +9445,19 @@ function wrapFiber(fiber) {
94439445
fiberToWrapper.set(fiber, wrapper));
94449446
return wrapper;
94459447
}
9446-
var devToolsConfig$jscomp$inline_1073 = {
9448+
var devToolsConfig$jscomp$inline_1074 = {
94479449
findFiberByHostInstance: function () {
94489450
throw Error("TestRenderer does not support findFiberByHostInstance()");
94499451
},
94509452
bundleType: 0,
9451-
version: "18.3.0-canary-6db7f4209-20231021",
9453+
version: "18.3.0-canary-779d59374-20231023",
94529454
rendererPackageName: "react-test-renderer"
94539455
};
9454-
var internals$jscomp$inline_1265 = {
9455-
bundleType: devToolsConfig$jscomp$inline_1073.bundleType,
9456-
version: devToolsConfig$jscomp$inline_1073.version,
9457-
rendererPackageName: devToolsConfig$jscomp$inline_1073.rendererPackageName,
9458-
rendererConfig: devToolsConfig$jscomp$inline_1073.rendererConfig,
9456+
var internals$jscomp$inline_1266 = {
9457+
bundleType: devToolsConfig$jscomp$inline_1074.bundleType,
9458+
version: devToolsConfig$jscomp$inline_1074.version,
9459+
rendererPackageName: devToolsConfig$jscomp$inline_1074.rendererPackageName,
9460+
rendererConfig: devToolsConfig$jscomp$inline_1074.rendererConfig,
94599461
overrideHookState: null,
94609462
overrideHookStateDeletePath: null,
94619463
overrideHookStateRenamePath: null,
@@ -9472,26 +9474,26 @@ var internals$jscomp$inline_1265 = {
94729474
return null === fiber ? null : fiber.stateNode;
94739475
},
94749476
findFiberByHostInstance:
9475-
devToolsConfig$jscomp$inline_1073.findFiberByHostInstance ||
9477+
devToolsConfig$jscomp$inline_1074.findFiberByHostInstance ||
94769478
emptyFindFiberByHostInstance,
94779479
findHostInstancesForRefresh: null,
94789480
scheduleRefresh: null,
94799481
scheduleRoot: null,
94809482
setRefreshHandler: null,
94819483
getCurrentFiber: null,
9482-
reconcilerVersion: "18.3.0-canary-6db7f4209-20231021"
9484+
reconcilerVersion: "18.3.0-canary-779d59374-20231023"
94839485
};
94849486
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
9485-
var hook$jscomp$inline_1266 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9487+
var hook$jscomp$inline_1267 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
94869488
if (
9487-
!hook$jscomp$inline_1266.isDisabled &&
9488-
hook$jscomp$inline_1266.supportsFiber
9489+
!hook$jscomp$inline_1267.isDisabled &&
9490+
hook$jscomp$inline_1267.supportsFiber
94899491
)
94909492
try {
9491-
(rendererID = hook$jscomp$inline_1266.inject(
9492-
internals$jscomp$inline_1265
9493+
(rendererID = hook$jscomp$inline_1267.inject(
9494+
internals$jscomp$inline_1266
94939495
)),
9494-
(injectedHook = hook$jscomp$inline_1266);
9496+
(injectedHook = hook$jscomp$inline_1267);
94959497
} catch (err) {}
94969498
}
94979499
exports._Scheduler = Scheduler;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if (
2727
}
2828
"use strict";
2929

30-
var ReactVersion = "18.3.0-canary-6db7f4209-20231021";
30+
var ReactVersion = "18.3.0-canary-779d59374-20231023";
3131

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,4 +580,4 @@ exports.useSyncExternalStore = function (
580580
exports.useTransition = function () {
581581
return ReactCurrentDispatcher.current.useTransition();
582582
};
583-
exports.version = "18.3.0-canary-6db7f4209-20231021";
583+
exports.version = "18.3.0-canary-779d59374-20231023";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ exports.useSyncExternalStore = function (
583583
exports.useTransition = function () {
584584
return ReactCurrentDispatcher.current.useTransition();
585585
};
586-
exports.version = "18.3.0-canary-6db7f4209-20231021";
586+
exports.version = "18.3.0-canary-779d59374-20231023";
587587

588588
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
589589
if (
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6db7f4209e6f32ebde298a0b7451710dd6aa3e19
1+
779d59374e8e852ce00728d895156a7574e1b456

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<30eb74bc13c38978deef06e3b48b5850>>
10+
* @generated SignedSource<<2852b7818fac619ab3ec01b1e52fa49a>>
1111
*/
1212

1313
'use strict';
@@ -4618,8 +4618,10 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {
46184618
root.entangledLanes |= spawnedLane;
46194619
root.entanglements[spawnedLaneIndex] |=
46204620
DeferredLane | // If the parent render task suspended, we must also entangle those lanes
4621-
// with the spawned task.
4622-
entangledLanes;
4621+
// with the spawned task, so that the deferred task includes all the same
4622+
// updates that the parent task did. We can exclude any lane that is not
4623+
// used for updates (e.g. Offscreen).
4624+
(entangledLanes & UpdateLanes);
46234625
}
46244626

46254627
function markRootEntangled(root, entangledLanes) {
@@ -23181,13 +23183,20 @@ function requestDeferredLane() {
2318123183
// If there are multiple useDeferredValue hooks in the same render, the
2318223184
// tasks that they spawn should all be batched together, so they should all
2318323185
// receive the same lane.
23184-
if (includesSomeLane(workInProgressRootRenderLanes, OffscreenLane)) {
23186+
// Check the priority of the current render to decide the priority of the
23187+
// deferred task.
23188+
// OffscreenLane is used for prerendering, but we also use OffscreenLane
23189+
// for incremental hydration. It's given the lowest priority because the
23190+
// initial HTML is the same as the final UI. But useDeferredValue during
23191+
// hydration is an exception — we need to upgrade the UI to the final
23192+
// value. So if we're currently hydrating, we treat it like a transition.
23193+
var isPrerendering =
23194+
includesSomeLane(workInProgressRootRenderLanes, OffscreenLane) &&
23195+
!getIsHydrating();
23196+
23197+
if (isPrerendering) {
2318523198
// There's only one OffscreenLane, so if it contains deferred work, we
2318623199
// should just reschedule using the same lane.
23187-
// TODO: We also use OffscreenLane for hydration, on the basis that the
23188-
// initial HTML is the same as the hydrated UI, but since the deferred
23189-
// task will change the UI, it should be treated like an update. Use
23190-
// TransitionHydrationLane to trigger selective hydration.
2319123200
workInProgressDeferredLane = OffscreenLane;
2319223201
} else {
2319323202
// Everything else is spawned as a transition.
@@ -27251,7 +27260,7 @@ function createFiberRoot(
2725127260
return root;
2725227261
}
2725327262

27254-
var ReactVersion = "18.3.0-canary-b286d49a";
27263+
var ReactVersion = "18.3.0-canary-fa7a00a2";
2725527264

2725627265
function createPortal$1(
2725727266
children,

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<f5971f814374f2eda5a1ab4609de44c9>>
10+
* @generated SignedSource<<b82de5fb1478e5883ad65538ea6b838f>>
1111
*/
1212

1313
"use strict";
@@ -1539,7 +1539,9 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {
15391539
var spawnedLaneIndex = 31 - clz32(spawnedLane);
15401540
root.entangledLanes |= spawnedLane;
15411541
root.entanglements[spawnedLaneIndex] =
1542-
root.entanglements[spawnedLaneIndex] | 1073741824 | entangledLanes;
1542+
root.entanglements[spawnedLaneIndex] |
1543+
1073741824 |
1544+
(entangledLanes & 4194218);
15431545
}
15441546
function markRootEntangled(root, entangledLanes) {
15451547
var rootEntangledLanes = (root.entangledLanes |= entangledLanes);
@@ -9533,7 +9535,7 @@ var roots = new Map(),
95339535
devToolsConfig$jscomp$inline_1048 = {
95349536
findFiberByHostInstance: getInstanceFromNode,
95359537
bundleType: 0,
9536-
version: "18.3.0-canary-db869081",
9538+
version: "18.3.0-canary-2afcfa14",
95379539
rendererPackageName: "react-native-renderer",
95389540
rendererConfig: {
95399541
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -9576,7 +9578,7 @@ var internals$jscomp$inline_1290 = {
95769578
scheduleRoot: null,
95779579
setRefreshHandler: null,
95789580
getCurrentFiber: null,
9579-
reconcilerVersion: "18.3.0-canary-db869081"
9581+
reconcilerVersion: "18.3.0-canary-2afcfa14"
95809582
};
95819583
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
95829584
var hook$jscomp$inline_1291 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<4c458b1ffae67751c0467a6058d6e4f2>>
10+
* @generated SignedSource<<933803924ed19507fb33fd09fca6dd3c>>
1111
*/
1212

1313

@@ -1638,7 +1638,9 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {
16381638
var spawnedLaneIndex = 31 - clz32(spawnedLane);
16391639
root.entangledLanes |= spawnedLane;
16401640
root.entanglements[spawnedLaneIndex] =
1641-
root.entanglements[spawnedLaneIndex] | 1073741824 | entangledLanes;
1641+
root.entanglements[spawnedLaneIndex] |
1642+
1073741824 |
1643+
(entangledLanes & 4194218);
16421644
}
16431645
function markRootEntangled(root, entangledLanes) {
16441646
var rootEntangledLanes = (root.entangledLanes |= entangledLanes);
@@ -10242,7 +10244,7 @@ var roots = new Map(),
1024210244
devToolsConfig$jscomp$inline_1126 = {
1024310245
findFiberByHostInstance: getInstanceFromNode,
1024410246
bundleType: 0,
10245-
version: "18.3.0-canary-0539669f",
10247+
version: "18.3.0-canary-8ec7f1ee",
1024610248
rendererPackageName: "react-native-renderer",
1024710249
rendererConfig: {
1024810250
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -10298,7 +10300,7 @@ var roots = new Map(),
1029810300
scheduleRoot: null,
1029910301
setRefreshHandler: null,
1030010302
getCurrentFiber: null,
10301-
reconcilerVersion: "18.3.0-canary-0539669f"
10303+
reconcilerVersion: "18.3.0-canary-8ec7f1ee"
1030210304
});
1030310305
exports.createPortal = function (children, containerTag) {
1030410306
return createPortal$1(

0 commit comments

Comments
 (0)