Skip to content

Commit ae27d3a

Browse files
committed
Add a test for updating the fallback
1 parent 12d275e commit ae27d3a

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

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

+75
Original file line numberDiff line numberDiff line change
@@ -3108,6 +3108,81 @@ describe('ReactSuspenseWithNoopRenderer', () => {
31083108
},
31093109
);
31103110

3111+
it(
3112+
'fallback component can update itself even after a high pri update to ' +
3113+
'the primary tree suspends',
3114+
async () => {
3115+
const {useState} = React;
3116+
const root = ReactNoop.createRoot();
3117+
3118+
let setAppText;
3119+
function App() {
3120+
const [text, _setText] = useState('A');
3121+
setAppText = _setText;
3122+
return (
3123+
<>
3124+
<Suspense fallback={<Fallback />}>
3125+
<AsyncText text={text} />
3126+
</Suspense>
3127+
</>
3128+
);
3129+
}
3130+
3131+
let setFallbackText;
3132+
function Fallback() {
3133+
const [text, _setText] = useState('Loading...');
3134+
setFallbackText = _setText;
3135+
return <Text text={text} />;
3136+
}
3137+
3138+
// Resolve the initial tree
3139+
await resolveText('A');
3140+
await ReactNoop.act(async () => {
3141+
root.render(<App />);
3142+
});
3143+
expect(Scheduler).toHaveYielded(['A']);
3144+
expect(root).toMatchRenderedOutput(<span prop="A" />);
3145+
3146+
// Schedule an update inside the Suspense boundary that suspends.
3147+
await ReactNoop.act(async () => {
3148+
setAppText('B');
3149+
});
3150+
expect(Scheduler).toHaveYielded(['Suspend! [B]', 'Loading...']);
3151+
// Commit the placeholder
3152+
await advanceTimers(250);
3153+
expect(root).toMatchRenderedOutput(
3154+
<>
3155+
<span hidden={true} prop="A" />
3156+
<span prop="Loading..." />
3157+
</>,
3158+
);
3159+
3160+
// Schedule a high pri update on the boundary, and a lower pri update
3161+
// on the fallback. We're testing to make sure the fallback can still
3162+
// update even though the primary tree is suspended.
3163+
await ReactNoop.act(async () => {
3164+
ReactNoop.discreteUpdates(() => {
3165+
setAppText('C');
3166+
});
3167+
setFallbackText('Still loading...');
3168+
});
3169+
3170+
expect(Scheduler).toHaveYielded([
3171+
// First try to update the suspended tree. It's still suspended.
3172+
'Suspend! [C]',
3173+
'Loading...',
3174+
// Then complete the update to the fallback.
3175+
'Still loading...',
3176+
]);
3177+
expect(root).toMatchRenderedOutput(
3178+
<>
3179+
<span hidden={true} prop="A" />
3180+
<span prop="Still loading..." />
3181+
</>,
3182+
);
3183+
},
3184+
);
3185+
31113186
it(
31123187
'regression: primary fragment fiber is not always part of setState ' +
31133188
'return path',

0 commit comments

Comments
 (0)