@@ -3645,4 +3645,117 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3645
3645
</ > ,
3646
3646
) ;
3647
3647
} ) ;
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
+ } ) ;
3648
3761
} ) ;
0 commit comments