Skip to content

Commit 0614b94

Browse files
committed
Add fix for unwinding context in sync update
1 parent 52ebf3b commit 0614b94

File tree

2 files changed

+11
-14
lines changed

2 files changed

+11
-14
lines changed

packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,8 +1886,7 @@ describe('ReactDOMServerSelectiveHydration', () => {
18861886
expect(initialSpan).toBe(spanRef);
18871887
});
18881888

1889-
// @gate experimental || www
1890-
it('regression test: can unwind context on selective hydration interruption', async () => {
1889+
it('regression test: can unwind context on selective hydration interruption for sync updates', async () => {
18911890
const Context = React.createContext('DefaultContext');
18921891

18931892
function ContextReader(props) {
@@ -1926,9 +1925,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
19261925
expect(Scheduler).toHaveYielded(['App', 'A', 'DefaultContext']);
19271926
const container = document.createElement('div');
19281927
container.innerHTML = finalHTML;
1929-
document.body.appendChild(container);
1930-
1931-
const spanA = container.getElementsByTagName('span')[0];
19321928

19331929
await act(async () => {
19341930
const root = ReactDOMClient.hydrateRoot(container, <App a="A" />);
@@ -1938,14 +1934,12 @@ describe('ReactDOMServerSelectiveHydration', () => {
19381934
'Commit',
19391935
]);
19401936

1941-
TODO_scheduleIdleDOMSchedulerTask(() => {
1937+
ReactDOM.flushSync(() => {
19421938
root.render(<App a="AA" />);
19431939
});
1944-
expect(Scheduler).toFlushAndYieldThrough(['App', 'A']);
1945-
1946-
dispatchClickEvent(spanA);
1947-
expect(Scheduler).toHaveYielded(['A']);
1948-
expect(Scheduler).toFlushAndYield([
1940+
expect(Scheduler).toHaveYielded([
1941+
'App',
1942+
'A',
19491943
'App',
19501944
'AA',
19511945
'DefaultContext',

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,7 +2072,6 @@ function renderRootSync(root: FiberRoot, lanes: Lanes) {
20722072
// Selective hydration. An update flowed into a dehydrated tree.
20732073
// Interrupt the current render so the work loop can switch to the
20742074
// hydration lane.
2075-
workInProgress = null;
20762075
workInProgressRootExitStatus = RootDidNotComplete;
20772076
break outer;
20782077
}
@@ -2097,8 +2096,12 @@ function renderRootSync(root: FiberRoot, lanes: Lanes) {
20972096
popDispatcher(prevDispatcher);
20982097
popCacheDispatcher(prevCacheDispatcher);
20992098

2100-
if (workInProgress !== null) {
2101-
// This is a sync render, so we should have finished the whole tree.
2099+
if (
2100+
workInProgress !== null &&
2101+
workInProgressRootExitStatus !== RootDidNotComplete
2102+
) {
2103+
// This is a sync render, so we should have finished the whole tree unless
2104+
// it is interrupted by selective hydration.
21022105
throw new Error(
21032106
'Cannot commit an incomplete root. This error is likely caused by a ' +
21042107
'bug in React. Please file an issue.',

0 commit comments

Comments
 (0)