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