diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
index eb5a72c91fadc..6da64f9cda992 100644
--- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
@@ -449,10 +449,9 @@ describe('ReactDOMServerPartialHydration', () => {
expect(deleted.length).toBe(0);
// Performing an update should force it to delete the boundary
- root.render();
-
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ root.render();
+ });
expect(hydrated.length).toBe(1);
expect(deleted.length).toBe(1);
@@ -945,13 +944,12 @@ describe('ReactDOMServerPartialHydration', () => {
root.render();
// At the same time, resolving the promise so that rendering can complete.
- suspend = false;
- resolve();
- await promise;
-
// This should first complete the hydration and then flush the update onto the hydrated state.
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ suspend = false;
+ resolve();
+ await promise;
+ });
// The new span should be the same since we should have successfully hydrated
// before changing it.
@@ -1093,9 +1091,9 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(null);
// Render an update, but leave it still suspended.
- root.render();
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ root.render();
+ });
// Flushing now should delete the existing content and show the fallback.
@@ -1104,12 +1102,11 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Loading...');
// Unsuspending shows the content.
- suspend = false;
- resolve();
- await promise;
-
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ suspend = false;
+ resolve();
+ await promise;
+ });
const span = container.getElementsByTagName('span')[0];
expect(span.textContent).toBe('Hi');
@@ -1174,23 +1171,21 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(span);
// Render an update, but leave it still suspended.
- root.render();
-
// Flushing now should delete the existing content and show the fallback.
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ root.render();
+ });
expect(container.getElementsByTagName('span').length).toBe(1);
expect(ref.current).toBe(span);
expect(container.textContent).toBe('');
// Unsuspending shows the content.
- suspend = false;
- resolve();
- await promise;
-
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ suspend = false;
+ resolve();
+ await promise;
+ });
expect(span.textContent).toBe('Hi');
expect(span.className).toBe('hi');
@@ -1252,20 +1247,21 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(null);
// Render an update, but leave it still suspended.
- root.render();
-
// Flushing now should delete the existing content and show the fallback.
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ root.render();
+ });
expect(container.getElementsByTagName('span').length).toBe(0);
expect(ref.current).toBe(null);
expect(container.textContent).toBe('Loading...');
// Unsuspending shows the content.
- suspend = false;
- resolve();
- await promise;
+ await act(async () => {
+ suspend = false;
+ resolve();
+ await promise;
+ });
Scheduler.unstable_flushAll();
jest.runAllTimers();
@@ -1490,13 +1486,12 @@ describe('ReactDOMServerPartialHydration', () => {
);
// At the same time, resolving the promise so that rendering can complete.
- suspend = false;
- resolve();
- await promise;
-
// This should first complete the hydration and then flush the update onto the hydrated state.
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ suspend = false;
+ resolve();
+ await promise;
+ });
// Since this should have been hydrated, this should still be the same span.
const newSpan = container.getElementsByTagName('span')[0];
@@ -1569,27 +1564,25 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(null);
// Render an update, but leave it still suspended.
- root.render(
-
-
- ,
- );
-
// Flushing now should delete the existing content and show the fallback.
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ root.render(
+
+
+ ,
+ );
+ });
expect(container.getElementsByTagName('span').length).toBe(0);
expect(ref.current).toBe(null);
expect(container.textContent).toBe('Loading...');
// Unsuspending shows the content.
- suspend = false;
- resolve();
- await promise;
-
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ suspend = false;
+ resolve();
+ await promise;
+ });
const span = container.getElementsByTagName('span')[0];
expect(span.textContent).toBe('Hi');
@@ -2320,16 +2313,15 @@ describe('ReactDOMServerPartialHydration', () => {
// Render an update, which will be higher or the same priority as pinging the hydration.
// The new update doesn't suspend.
- root.render(
-
-
- ,
- );
-
// Since we're still suspended on the original data, we can't hydrate.
// This will force all expiration times to flush.
- Scheduler.unstable_flushAll();
- jest.runAllTimers();
+ await act(async () => {
+ root.render(
+
+
+ ,
+ );
+ });
// This will now be a new span because we weren't able to hydrate before
const newSpan = container.getElementsByTagName('span')[0];
diff --git a/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js
index d38a98672ac03..08a89e09d5256 100644
--- a/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js
+++ b/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js
@@ -1786,7 +1786,7 @@ describe('ReactDOMServerSelectiveHydration', () => {
document.body.removeChild(container);
});
- it('can force hydration in response to sync update', () => {
+ it('can force hydration in response to sync update', async () => {
function Child({text}) {
Scheduler.unstable_yieldValue(`Child ${text}`);
return (spanRef = ref)}>{text};
@@ -1812,15 +1812,17 @@ describe('ReactDOMServerSelectiveHydration', () => {
const root = ReactDOMClient.hydrateRoot(container, );
expect(Scheduler).toFlushUntilNextPaint(['App A']);
- ReactDOM.flushSync(() => {
- root.render();
+ await act(async () => {
+ ReactDOM.flushSync(() => {
+ root.render();
+ });
});
expect(Scheduler).toHaveYielded(['App B', 'Child A', 'App B', 'Child B']);
expect(initialSpan).toBe(spanRef);
});
// @gate experimental || www
- it('can force hydration in response to continuous update', () => {
+ it('can force hydration in response to continuous update', async () => {
function Child({text}) {
Scheduler.unstable_yieldValue(`Child ${text}`);
return (spanRef = ref)}>{text};
@@ -1846,14 +1848,17 @@ describe('ReactDOMServerSelectiveHydration', () => {
const root = ReactDOMClient.hydrateRoot(container, );
expect(Scheduler).toFlushUntilNextPaint(['App A']);
- TODO_scheduleContinuousSchedulerTask(() => {
- root.render();
+ await act(async () => {
+ TODO_scheduleContinuousSchedulerTask(() => {
+ root.render();
+ });
});
- expect(Scheduler).toFlushAndYield(['App B', 'Child A', 'App B', 'Child B']);
+
+ expect(Scheduler).toHaveYielded(['App B', 'Child A', 'App B', 'Child B']);
expect(initialSpan).toBe(spanRef);
});
- it('can force hydration in response to default update', () => {
+ it('can force hydration in response to default update', async () => {
function Child({text}) {
Scheduler.unstable_yieldValue(`Child ${text}`);
return (spanRef = ref)}>{text};
@@ -1878,11 +1883,10 @@ describe('ReactDOMServerSelectiveHydration', () => {
const initialSpan = container.getElementsByTagName('span')[0];
const root = ReactDOMClient.hydrateRoot(container, );
expect(Scheduler).toFlushUntilNextPaint(['App A']);
-
- ReactDOM.unstable_batchedUpdates(() => {
+ await act(async () => {
root.render();
});
- expect(Scheduler).toFlushAndYield(['App B', 'Child A', 'App B', 'Child B']);
+ expect(Scheduler).toHaveYielded(['App B', 'Child A', 'App B', 'Child B']);
expect(initialSpan).toBe(spanRef);
});
diff --git a/packages/react-reconciler/src/ReactFiberLane.js b/packages/react-reconciler/src/ReactFiberLane.js
index b88cba0f2a674..1675fa0f23142 100644
--- a/packages/react-reconciler/src/ReactFiberLane.js
+++ b/packages/react-reconciler/src/ReactFiberLane.js
@@ -766,14 +766,11 @@ export function getBumpedLaneForHydration(
const renderLane = getHighestPriorityLane(renderLanes);
let lane;
- /*
- TODO:
if (enableUnifiedSyncLane) {
if ((renderLane & SyncUpdateLanes) !== NoLane) {
lane = SyncHydrationLane;
}
}
- */
if (!lane) {
switch (renderLane) {
case SyncLane: