Skip to content

Commit 3ff151d

Browse files
committed
Add another test for facebook#18515 using pings
Adds a regression test for the same underlying bug as facebook#18515 but using pings. Test already passes, but I confirmed it fails if you revert the fix in facebook#18515.
1 parent ddc4b65 commit 3ff151d

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3645,4 +3645,117 @@ describe('ReactSuspenseWithNoopRenderer', () => {
36453645
</>,
36463646
);
36473647
});
3648+
3649+
it('regression: ping at high priority causes update to be dropped', async () => {
3650+
const {useState, useTransition} = React;
3651+
3652+
let setTextA;
3653+
function A() {
3654+
const [textA, _setTextA] = useState('A');
3655+
setTextA = _setTextA;
3656+
return (
3657+
<Suspense fallback={<Text text="Loading..." />}>
3658+
<AsyncText text={textA} />
3659+
</Suspense>
3660+
);
3661+
}
3662+
3663+
let setTextB;
3664+
let startTransition;
3665+
function B() {
3666+
const [textB, _setTextB] = useState('B');
3667+
const [_startTransition] = useTransition({timeoutMs: 10000});
3668+
startTransition = _startTransition;
3669+
setTextB = _setTextB;
3670+
return (
3671+
<Suspense fallback={<Text text="Loading..." />}>
3672+
<AsyncText text={textB} />
3673+
</Suspense>
3674+
);
3675+
}
3676+
3677+
function App() {
3678+
return (
3679+
<>
3680+
<A />
3681+
<B />
3682+
</>
3683+
);
3684+
}
3685+
3686+
const root = ReactNoop.createRoot();
3687+
await ReactNoop.act(async () => {
3688+
await resolveText('A');
3689+
await resolveText('B');
3690+
root.render(<App />);
3691+
});
3692+
expect(Scheduler).toHaveYielded(['A', 'B']);
3693+
expect(root).toMatchRenderedOutput(
3694+
<>
3695+
<span prop="A" />
3696+
<span prop="B" />
3697+
</>,
3698+
);
3699+
3700+
await ReactNoop.act(async () => {
3701+
// Triggers suspense at normal pri
3702+
setTextA('A1');
3703+
// Triggers in an unrelated tree at a different pri
3704+
startTransition(() => {
3705+
// Update A again so that it doesn't suspend on A1. That way we can ping
3706+
// the A1 update without also pinging this one. This is a workaround
3707+
// because there's currently no way to render at a lower priority (B2)
3708+
// without including all updates at higher priority (A1).
3709+
setTextA('A2');
3710+
setTextB('B2');
3711+
});
3712+
});
3713+
expect(Scheduler).toHaveYielded([
3714+
'B',
3715+
'Suspend! [A1]',
3716+
'Loading...',
3717+
3718+
'Suspend! [A2]',
3719+
'Loading...',
3720+
'Suspend! [B2]',
3721+
'Loading...',
3722+
]);
3723+
expect(root).toMatchRenderedOutput(
3724+
<>
3725+
<span prop="A" />
3726+
<span prop="B" />
3727+
</>,
3728+
);
3729+
3730+
await ReactNoop.act(async () => {
3731+
resolveText('A1');
3732+
});
3733+
expect(Scheduler).toHaveYielded([
3734+
'Promise resolved [A1]',
3735+
'A1',
3736+
'Suspend! [A2]',
3737+
'Loading...',
3738+
'Suspend! [B2]',
3739+
'Loading...',
3740+
]);
3741+
expect(root).toMatchRenderedOutput(
3742+
<>
3743+
<span prop="A1" />
3744+
<span prop="B" />
3745+
</>,
3746+
);
3747+
3748+
// Commit the placeholder
3749+
Scheduler.unstable_advanceTime(20000);
3750+
await advanceTimers(20000);
3751+
3752+
expect(root).toMatchRenderedOutput(
3753+
<>
3754+
<span hidden={true} prop="A1" />
3755+
<span prop="Loading..." />
3756+
<span hidden={true} prop="B" />
3757+
<span prop="Loading..." />
3758+
</>,
3759+
);
3760+
});
36483761
});

0 commit comments

Comments
 (0)