File tree 4 files changed +45
-0
lines changed
4 files changed +45
-0
lines changed Original file line number Diff line number Diff line change @@ -3026,6 +3026,12 @@ function updateDeferredValueImpl<T>(
3026
3026
}
3027
3027
}
3028
3028
3029
+ function releaseAsyncTransition ( ) {
3030
+ if ( __DEV__ ) {
3031
+ ReactSharedInternals . asyncTransitions -- ;
3032
+ }
3033
+ }
3034
+
3029
3035
function startTransition < S > (
3030
3036
fiber : Fiber ,
3031
3037
queue : UpdateQueue < S | Thenable < S > , BasicStateAction < S | Thenable < S >>> ,
@@ -3083,6 +3089,11 @@ function startTransition<S>(
3083
3089
typeof returnValue . then === 'function'
3084
3090
) {
3085
3091
const thenable = ( ( returnValue : any ) : Thenable < mixed > ) ;
3092
+ if ( __DEV__ ) {
3093
+ // Keep track of the number of async transitions still running so we can warn.
3094
+ ReactSharedInternals. asyncTransitions ++ ;
3095
+ thenable . then ( releaseAsyncTransition , releaseAsyncTransition ) ;
3096
+ }
3086
3097
// Create a thenable that resolves to `finishedState` once the async
3087
3098
// action has completed.
3088
3099
const thenableForFinishedState = chainThenableValue (
Original file line number Diff line number Diff line change @@ -38,6 +38,9 @@ export type SharedStateClient = {
38
38
// ReactCurrentActQueue
39
39
actQueue : null | Array < RendererTask > ,
40
40
41
+ // When zero this means we're outside an async startTransition.
42
+ asyncTransitions : number ,
43
+
41
44
// Used to reproduce behavior of `batchedUpdates` in legacy mode.
42
45
isBatchingLegacy : boolean ,
43
46
didScheduleLegacyUpdate : boolean ,
@@ -74,6 +77,7 @@ if (enableViewTransition) {
74
77
75
78
if ( __DEV__ ) {
76
79
ReactSharedInternals . actQueue = null ;
80
+ ReactSharedInternals . asyncTransitions = 0 ;
77
81
ReactSharedInternals . isBatchingLegacy = false ;
78
82
ReactSharedInternals . didScheduleLegacyUpdate = false ;
79
83
ReactSharedInternals . didUsePromise = false ;
Original file line number Diff line number Diff line change @@ -37,6 +37,12 @@ export type Transition = {
37
37
...
38
38
} ;
39
39
40
+ function releaseAsyncTransition ( ) {
41
+ if ( __DEV__ ) {
42
+ ReactSharedInternals . asyncTransitions -- ;
43
+ }
44
+ }
45
+
40
46
export function startTransition (
41
47
scope : ( ) = > void ,
42
48
options ?: StartTransitionOptions ,
@@ -67,6 +73,11 @@ export function startTransition(
67
73
returnValue !== null &&
68
74
typeof returnValue . then === 'function'
69
75
) {
76
+ if ( __DEV__ ) {
77
+ // Keep track of the number of async transitions still running so we can warn.
78
+ ReactSharedInternals . asyncTransitions ++ ;
79
+ returnValue . then ( releaseAsyncTransition , releaseAsyncTransition ) ;
80
+ }
70
81
returnValue . then ( noop , reportGlobalError ) ;
71
82
}
72
83
} catch ( error ) {
Original file line number Diff line number Diff line change @@ -45,6 +45,25 @@ export function addTransitionType(type: string): void {
45
45
pendingTransitionTypes = pendingGestureTransitionTypes = [ ] ;
46
46
}
47
47
} else {
48
+ if ( __DEV__ ) {
49
+ if (
50
+ ReactSharedInternals . T === null &&
51
+ ReactSharedInternals . asyncTransitions === 0
52
+ ) {
53
+ if ( enableGestureTransition ) {
54
+ console . error (
55
+ 'addTransitionType can only be called inside a `startTransition()` ' +
56
+ 'or `startGestureTransition()` callback. ' +
57
+ 'It must be associated with a specific Transition.' ,
58
+ ) ;
59
+ } else {
60
+ console . error (
61
+ 'addTransitionType can only be called inside a `startTransition()` ' +
62
+ 'callback. It must be associated with a specific Transition.' ,
63
+ ) ;
64
+ }
65
+ }
66
+ }
48
67
// Otherwise we're either inside a synchronous startTransition
49
68
// or in the async gap of one, which we track globally.
50
69
pendingTransitionTypes = ReactSharedInternals . V ;
You can’t perform that action at this time.
0 commit comments