@@ -2775,4 +2775,193 @@ describe('Store', () => {
27752775 <Suspense name="content" rects={[{x:1,y:2,width:4,height:1}]}>
27762776 ` ) ;
27772777 } ) ;
2778+
2779+ // @reactVersion >= 18.0
2780+ it ( 'can reconcile resuspended Suspense with Suspense in fallback positions' , async ( ) => {
2781+ let resolveHeadFallback ;
2782+ let resolveHeadContent ;
2783+ let resolveMainFallback ;
2784+ let resolveMainContent ;
2785+
2786+ function Component ( { children, promise} ) {
2787+ if ( promise ) {
2788+ React . use ( promise ) ;
2789+ }
2790+ return < div > { children } </ div > ;
2791+ }
2792+
2793+ function WithSuspenseInFallback ( { fallbackPromise, contentPromise, name} ) {
2794+ return (
2795+ < React . Suspense
2796+ name = { name }
2797+ fallback = {
2798+ < React . Suspense
2799+ name = { `${ name } -fallback` }
2800+ fallback = {
2801+ < Component key = { `${ name } -fallback-fallback` } >
2802+ Loading fallback...
2803+ </ Component >
2804+ } >
2805+ < Component
2806+ key = { `${ name } -fallback-content` }
2807+ promise = { fallbackPromise } >
2808+ Loading...
2809+ </ Component >
2810+ </ React . Suspense >
2811+ } >
2812+ < Component key = { `${ name } -content` } promise = { contentPromise } >
2813+ done
2814+ </ Component >
2815+ </ React . Suspense >
2816+ ) ;
2817+ }
2818+
2819+ function App ( {
2820+ headFallbackPromise,
2821+ headContentPromise,
2822+ mainContentPromise,
2823+ mainFallbackPromise,
2824+ tailContentPromise,
2825+ tailFallbackPromise,
2826+ } ) {
2827+ return (
2828+ < >
2829+ < WithSuspenseInFallback
2830+ fallbackPromise = { headFallbackPromise }
2831+ contentPromise = { headContentPromise }
2832+ name = "head"
2833+ />
2834+ < WithSuspenseInFallback
2835+ fallbackPromise = { mainFallbackPromise }
2836+ contentPromise = { mainContentPromise }
2837+ name = "main"
2838+ />
2839+ </ >
2840+ ) ;
2841+ }
2842+
2843+ const initialHeadContentPromise = new Promise ( resolve => {
2844+ resolveHeadContent = resolve ;
2845+ } ) ;
2846+ const initialHeadFallbackPromise = new Promise ( resolve => {
2847+ resolveHeadFallback = resolve ;
2848+ } ) ;
2849+ const initialMainContentPromise = new Promise ( resolve => {
2850+ resolveMainContent = resolve ;
2851+ } ) ;
2852+ const initialMainFallbackPromise = new Promise ( resolve => {
2853+ resolveMainFallback = resolve ;
2854+ } ) ;
2855+ await actAsync ( ( ) =>
2856+ render (
2857+ < App
2858+ headFallbackPromise = { initialHeadFallbackPromise }
2859+ headContentPromise = { initialHeadContentPromise }
2860+ mainContentPromise = { initialMainContentPromise }
2861+ mainFallbackPromise = { initialMainFallbackPromise }
2862+ /> ,
2863+ ) ,
2864+ ) ;
2865+
2866+ expect ( store ) . toMatchInlineSnapshot ( `
2867+ [root]
2868+ ▾ <App>
2869+ ▾ <WithSuspenseInFallback>
2870+ ▾ <Suspense name="head">
2871+ ▾ <Suspense name="head-fallback">
2872+ <Component key="head-fallback-fallback">
2873+ ▾ <WithSuspenseInFallback>
2874+ ▾ <Suspense name="main">
2875+ ▾ <Suspense name="main-fallback">
2876+ <Component key="main-fallback-fallback">
2877+ [shell]
2878+ <Suspense name="head" rects={null}>
2879+ <Suspense name="head-fallback" rects={null}>
2880+ <Suspense name="main" rects={null}>
2881+ <Suspense name="main-fallback" rects={null}>
2882+ ` ) ;
2883+
2884+ await actAsync ( ( ) => {
2885+ resolveHeadFallback ( ) ;
2886+ resolveMainFallback ( ) ;
2887+ resolveHeadContent ( ) ;
2888+ resolveMainContent ( ) ;
2889+ } ) ;
2890+
2891+ expect ( store ) . toMatchInlineSnapshot ( `
2892+ [root]
2893+ ▾ <App>
2894+ ▾ <WithSuspenseInFallback>
2895+ ▾ <Suspense name="head">
2896+ <Component key="head-content">
2897+ ▾ <WithSuspenseInFallback>
2898+ ▾ <Suspense name="main">
2899+ <Component key="main-content">
2900+ [shell]
2901+ <Suspense name="head" rects={[{x:1,y:2,width:4,height:1}]}>
2902+ <Suspense name="main" rects={[{x:1,y:2,width:4,height:1}]}>
2903+ ` ) ;
2904+
2905+ // Resuspend head content
2906+ const nextHeadContentPromise = new Promise ( resolve => {
2907+ resolveHeadContent = resolve ;
2908+ } ) ;
2909+ await actAsync ( ( ) =>
2910+ render (
2911+ < App
2912+ headFallbackPromise = { initialHeadFallbackPromise }
2913+ headContentPromise = { nextHeadContentPromise }
2914+ mainContentPromise = { initialMainContentPromise }
2915+ mainFallbackPromise = { initialMainFallbackPromise }
2916+ /> ,
2917+ ) ,
2918+ ) ;
2919+
2920+ expect ( store ) . toMatchInlineSnapshot ( `
2921+ [root]
2922+ ▾ <App>
2923+ ▾ <WithSuspenseInFallback>
2924+ ▾ <Suspense name="head">
2925+ ▾ <Suspense name="head-fallback">
2926+ <Component key="head-fallback-content">
2927+ ▾ <WithSuspenseInFallback>
2928+ ▾ <Suspense name="main">
2929+ <Component key="main-content">
2930+ [shell]
2931+ <Suspense name="head" rects={[{x:1,y:2,width:4,height:1}]}>
2932+ <Suspense name="head-fallback" rects={[{x:1,y:2,width:10,height:1}]}>
2933+ <Suspense name="main" rects={[{x:1,y:2,width:4,height:1}]}>
2934+ ` ) ;
2935+
2936+ // Resuspend head fallback
2937+ const nextHeadFallbackPromise = new Promise ( resolve => {
2938+ resolveHeadFallback = resolve ;
2939+ } ) ;
2940+ await actAsync ( ( ) =>
2941+ render (
2942+ < App
2943+ headFallbackPromise = { nextHeadFallbackPromise }
2944+ headContentPromise = { nextHeadContentPromise }
2945+ mainContentPromise = { initialMainContentPromise }
2946+ mainFallbackPromise = { initialMainFallbackPromise }
2947+ /> ,
2948+ ) ,
2949+ ) ;
2950+
2951+ expect ( store ) . toMatchInlineSnapshot ( `
2952+ [root]
2953+ ▾ <App>
2954+ ▾ <WithSuspenseInFallback>
2955+ ▾ <Suspense name="head">
2956+ ▾ <Suspense name="head-fallback">
2957+ <Component key="head-fallback-fallback">
2958+ ▾ <WithSuspenseInFallback>
2959+ ▾ <Suspense name="main">
2960+ <Component key="main-content">
2961+ [shell]
2962+ <Suspense name="head" rects={[{x:1,y:2,width:4,height:1}]}>
2963+ <Suspense name="head-fallback" rects={[{x:1,y:2,width:10,height:1}]}>
2964+ <Suspense name="main" rects={[{x:1,y:2,width:4,height:1}]}>
2965+ ` ) ;
2966+ } ) ;
27782967} ) ;
0 commit comments