@@ -1884,9 +1884,7 @@ function forceStoreRerender(fiber: Fiber) {
1884
1884
}
1885
1885
}
1886
1886
1887
- function mountState < S > (
1888
- initialState: (() => S ) | S ,
1889
- ) : [ S , Dispatch < BasicStateAction < S > > ] {
1887
+ function mountStateImpl < S > (initialState: (() => S ) | S ) : Hook {
1890
1888
const hook = mountWorkInProgressHook ( ) ;
1891
1889
if ( typeof initialState === 'function' ) {
1892
1890
// $FlowFixMe[incompatible-use]: Flow doesn't like mixed types
@@ -1901,9 +1899,20 @@ function mountState<S>(
1901
1899
lastRenderedState : ( initialState : any ) ,
1902
1900
} ;
1903
1901
hook.queue = queue;
1904
- const dispatch: Dispatch< BasicStateAction < S > > = ( queue . dispatch =
1905
- ( dispatchSetState . bind ( null , currentlyRenderingFiber , queue ) : any ) ) ;
1906
- return [ hook . memoizedState , dispatch ] ;
1902
+ const dispatch: Dispatch< BasicStateAction < S > > = ( dispatchSetState . bind (
1903
+ null ,
1904
+ currentlyRenderingFiber ,
1905
+ queue ,
1906
+ ) : any ) ;
1907
+ queue . dispatch = dispatch ;
1908
+ return hook ;
1909
+ }
1910
+
1911
+ function mountState < S > (
1912
+ initialState: (() => S ) | S ,
1913
+ ) : [ S , Dispatch < BasicStateAction < S > > ] {
1914
+ const hook = mountStateImpl ( initialState ) ;
1915
+ return [ hook . memoizedState , hook . queue . dispatch ] ;
1907
1916
}
1908
1917
1909
1918
function updateState< S > (
@@ -2469,9 +2478,10 @@ function updateDeferredValueImpl<T>(hook: Hook, prevValue: T, value: T): T {
2469
2478
}
2470
2479
2471
2480
function startTransition < S > (
2481
+ fiber: Fiber,
2482
+ queue: UpdateQueue< S | Thenable < S > , BasicStateAction< S | Thenable < S > >> ,
2472
2483
pendingState : S ,
2473
2484
finishedState : S ,
2474
- setPending: (Thenable< S > | S) => void ,
2475
2485
callback : ( ) => mixed ,
2476
2486
options ?: StartTransitionOptions ,
2477
2487
) : void {
@@ -2482,7 +2492,7 @@ function startTransition<S>(
2482
2492
2483
2493
const prevTransition = ReactCurrentBatchConfig . transition ;
2484
2494
ReactCurrentBatchConfig . transition = null ;
2485
- setPending ( pendingState ) ;
2495
+ dispatchSetState ( fiber , queue , pendingState ) ;
2486
2496
const currentTransition = ( ReactCurrentBatchConfig . transition =
2487
2497
( { } : BatchConfigTransition ) ) ;
2488
2498
@@ -2509,10 +2519,10 @@ function startTransition<S>(
2509
2519
returnValue ,
2510
2520
finishedState ,
2511
2521
) ;
2512
- setPending ( maybeThenable ) ;
2522
+ dispatchSetState ( fiber , queue , maybeThenable ) ;
2513
2523
} else {
2514
2524
// Async actions are not enabled.
2515
- setPending ( finishedState ) ;
2525
+ dispatchSetState ( fiber , queue , finishedState ) ;
2516
2526
callback ( ) ;
2517
2527
}
2518
2528
} catch ( error ) {
@@ -2525,7 +2535,7 @@ function startTransition<S>(
2525
2535
status : 'rejected' ,
2526
2536
reason : error ,
2527
2537
} ;
2528
- setPending ( rejectedThenable ) ;
2538
+ dispatchSetState ( fiber , queue , rejectedThenable ) ;
2529
2539
} else {
2530
2540
// The error rethrowing behavior is only enabled when the async actions
2531
2541
// feature is on, even for sync actions.
@@ -2577,36 +2587,39 @@ export function startHostTransition<F>(
2577
2587
) ;
2578
2588
}
2579
2589
2580
- let setPending;
2590
+ let queue: UpdateQueue<
2591
+ Thenable < TransitionStatus > | TransitionStatus,
2592
+ BasicStateAction< Thenable < TransitionStatus > | TransitionStatus> ,
2593
+ > ;
2581
2594
if ( formFiber . memoizedState === null ) {
2582
2595
// Upgrade this host component fiber to be stateful. We're going to pretend
2583
2596
// it was stateful all along so we can reuse most of the implementation
2584
2597
// for function components and useTransition.
2585
2598
//
2586
2599
// Create the state hook used by TransitionAwareHostComponent. This is
2587
2600
// essentially an inlined version of mountState.
2588
- const queue : UpdateQueue <
2589
- Thenable < TransitionStatus > | TransitionStatus ,
2601
+ const newQueue : UpdateQueue <
2590
2602
Thenable < TransitionStatus > | TransitionStatus ,
2603
+ BasicStateAction < Thenable < TransitionStatus > | TransitionStatus > ,
2591
2604
> = {
2592
2605
pending : null ,
2593
2606
lanes : NoLanes ,
2594
- dispatch : null ,
2607
+ // We're going to cheat and intentionally not create a bound dispatch
2608
+ // method, because we can call it directly in startTransition.
2609
+ dispatch : ( null : any ) ,
2595
2610
lastRenderedReducer : basicStateReducer ,
2596
2611
lastRenderedState : NoPendingHostTransition ,
2597
2612
} ;
2613
+ queue = newQueue ;
2614
+
2598
2615
const stateHook : Hook = {
2599
2616
memoizedState : NoPendingHostTransition ,
2600
2617
baseState : NoPendingHostTransition ,
2601
2618
baseQueue : null ,
2602
- queue : queue ,
2619
+ queue : newQueue ,
2603
2620
next : null ,
2604
2621
} ;
2605
2622
2606
- const dispatch : ( Thenable < TransitionStatus > | TransitionStatus ) = > void =
2607
- ( dispatchSetState . bind ( null , formFiber , queue ) : any ) ;
2608
- setPending = queue . dispatch = dispatch ;
2609
-
2610
2623
// Add the state hook to both fiber alternates. The idea is that the fiber
2611
2624
// had this hook all along.
2612
2625
formFiber . memoizedState = stateHook ;
@@ -2617,15 +2630,14 @@ export function startHostTransition<F>(
2617
2630
} else {
2618
2631
// This fiber was already upgraded to be stateful.
2619
2632
const stateHook : Hook = formFiber . memoizedState ;
2620
- const dispatch : ( Thenable < TransitionStatus > | TransitionStatus ) = > void =
2621
- stateHook . queue . dispatch ;
2622
- setPending = dispatch ;
2633
+ queue = stateHook . queue ;
2623
2634
}
2624
2635
2625
2636
startTransition(
2637
+ formFiber,
2638
+ queue,
2626
2639
pendingState,
2627
2640
NoPendingHostTransition,
2628
- setPending,
2629
2641
// TODO: We can avoid this extra wrapper, somehow. Figure out layering
2630
2642
// once more of this function is implemented.
2631
2643
() => callback ( formData ) ,
@@ -2636,9 +2648,15 @@ function mountTransition(): [
2636
2648
boolean ,
2637
2649
( callback : ( ) => void , options ?: StartTransitionOptions ) => void ,
2638
2650
] {
2639
- const [ , setPending ] = mountState ( ( false : Thenable < boolean > | boolean ) ) ;
2651
+ const stateHook = mountStateImpl ( ( false : Thenable < boolean > | boolean ) ) ;
2640
2652
// The `start` method never changes.
2641
- const start = startTransition . bind ( null , true , false , setPending ) ;
2653
+ const start = startTransition . bind (
2654
+ null ,
2655
+ currentlyRenderingFiber ,
2656
+ stateHook . queue ,
2657
+ true ,
2658
+ false ,
2659
+ ) ;
2642
2660
const hook = mountWorkInProgressHook ( ) ;
2643
2661
hook . memoizedState = start ;
2644
2662
return [ false , start ] ;
0 commit comments