Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for #18657 #18663

Merged
merged 2 commits into from Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 1 addition & 5 deletions packages/react-reconciler/src/ReactFiberBeginWork.new.js
Expand Up @@ -1681,11 +1681,7 @@ function getRemainingWorkInPrimaryTree(
// This boundary already timed out. Check if this render includes the level
// that previously suspended.
const baseTime = currentSuspenseState.baseTime;
if (
baseTime !== NoWork &&
baseTime < renderExpirationTime &&
baseTime > currentChildExpirationTime
) {
if (baseTime !== NoWork && baseTime < renderExpirationTime) {
// There's pending work at a lower level that might now be unblocked.
return baseTime;
}
Expand Down
6 changes: 1 addition & 5 deletions packages/react-reconciler/src/ReactFiberBeginWork.old.js
Expand Up @@ -1681,11 +1681,7 @@ function getRemainingWorkInPrimaryTree(
// This boundary already timed out. Check if this render includes the level
// that previously suspended.
const baseTime = currentSuspenseState.baseTime;
if (
baseTime !== NoWork &&
baseTime < renderExpirationTime &&
baseTime > currentChildExpirationTime
) {
if (baseTime !== NoWork && baseTime < renderExpirationTime) {
// There's pending work at a lower level that might now be unblocked.
return baseTime;
}
Expand Down
Expand Up @@ -3869,4 +3869,53 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(root).toMatchRenderedOutput(<span prop="b" />);
});
});

it('regression: #18657', async () => {
const {useState} = React;

let setText;
function App() {
const [text, _setText] = useState('A');
setText = _setText;
return <AsyncText text={text} />;
}

const root = ReactNoop.createRoot();
await ReactNoop.act(async () => {
await resolveText('A');
root.render(
<Suspense fallback={<Text text="Loading..." />}>
<App />
</Suspense>,
);
});
expect(Scheduler).toHaveYielded(['A']);
expect(root).toMatchRenderedOutput(<span prop="A" />);

await ReactNoop.act(async () => {
setText('B');
Scheduler.unstable_runWithPriority(
Scheduler.unstable_IdlePriority,
() => {
setText('B');
},
);
// Suspend the first update. The second update doesn't run because it has
// Idle priority.
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);

// Commit the fallback. Now we'll try working on Idle.
jest.runAllTimers();

// It also suspends.
expect(Scheduler).toFlushAndYield(['Suspend! [B]']);
});

await ReactNoop.act(async () => {
setText('B');
await resolveText('B');
});
expect(Scheduler).toHaveYielded(['Promise resolved [B]', 'B']);
expect(root).toMatchRenderedOutput(<span prop="B" />);
});
});