275
// goes from visible to hidden in synchronous update.
276
class ClassComponent extends React.Component {
277
render() {
278
- return <Text text="Child" />;
278
+ return <Text text="child" />;
279
}
280
281
componentWillUnmount() {
287
}
288
}
289
290
- let _setIsVisible;
291
- let isFirstRender = true;
290
+ const root = ReactNoop.createRoot();
291
+ await act(async () => {
292
+ // Outer and inner offscreen are hidden.
293
+ root.render(
294
+ <Offscreen mode={'hidden'}>
295
+ <Offscreen mode={'hidden'}>
296
+ <ClassComponent />
297
+ </Offscreen>
298
+ </Offscreen>,
299
+ );
300
+ });
301
293
- function App() {
294
- const [isVisible, setIsVisible] = React.useState(true);
295
- _setIsVisible = setIsVisible;
296
- if (isFirstRender === true) {
297
- setIsVisible(false);
298
- isFirstRender = false;
299
- }
302
+ expect(Scheduler).toHaveYielded(['child']);
303
+ expect(root).toMatchRenderedOutput(<span hidden={true} prop="child" />);
304
301
- return (
302
- <Offscreen mode="hidden">
303
- <Offscreen mode={isVisible ? 'visible' : 'hidden'}>
305
+ await act(async () => {
306
+ // Inner offscreen is visible.
307
+ root.render(
308
+ <Offscreen mode={'hidden'}>
309
+ <Offscreen mode={'visible'}>
310
<ClassComponent />
311
</Offscreen>
306
- </Offscreen>
312
+ </Offscreen>,
313
);
308
- }
314
+ });
315
+
316
+ expect(Scheduler).toHaveYielded(['child']);
317
+ expect(root).toMatchRenderedOutput(<span hidden={true} prop="child" />);
318
310
- const root = ReactNoop.createRoot();
319
await act(async () => {
312
- root.render(<App />);
320
+ // Inner offscreen is hidden.
321
+ root.render(
322
+ <Offscreen mode={'hidden'}>
323
+ <Offscreen mode={'hidden'}>
324
+ <ClassComponent />
325
+ </Offscreen>
326
+ </Offscreen>,
327
+ );
328
});
329
315
- expect(Scheduler).toHaveYielded(['Child']);
316
- expect(root).toMatchRenderedOutput(<span hidden={true} prop="Child" />);
330
+ expect(Scheduler).toHaveYielded(['child']);
331
+ expect(root).toMatchRenderedOutput(<span hidden={true} prop="child" />);
332
333
await act(async () => {
319
- _setIsVisible(true);
334
+ // Inner offscreen is visible.
335
+ root.render(
336
+ <Offscreen mode={'hidden'}>
337
+ <Offscreen mode={'visible'}>
338
+ <ClassComponent />
339
+ </Offscreen>
340
+ </Offscreen>,
341
+ );
342
});
343
322
- expect(Scheduler).toHaveYielded(['Child']);
323
- expect(root).toMatchRenderedOutput(<span hidden={true} prop="Child" />);
344
+ Scheduler.unstable_clearYields();
345
+
346
+ await act(async () => {
347
+ // Outer offscreen is visible.
348
+ // Inner offscreen is hidden.
349
+ root.render(
350
+ <Offscreen mode={'visible'}>
351
+ <Offscreen mode={'hidden'}>
352
+ <ClassComponent />
353
+ </Offscreen>
354
+ </Offscreen>,
355
+ );
356
+ });
357
+
358
+ expect(Scheduler).toHaveYielded(['child']);
359
360
await act(async () => {
326
- _setIsVisible(false);
361
+ // Outer offscreen is hidden.
362
+ // Inner offscreen is visible.
363
+ root.render(
364
+ <Offscreen mode={'hidden'}>
365
+ <Offscreen mode={'visible'}>
366
+ <ClassComponent />
367
+ </Offscreen>
368
+ </Offscreen>,
369
+ );
370
});
371
329
- expect(Scheduler).toHaveYielded(['Child']);
330
- expect(root).toMatchRenderedOutput(<span hidden={true} prop="Child" />);
372
+ expect(Scheduler).toHaveYielded(['child']);
373
});
374
375
// @gate enableOffscreen