@@ -174,16 +174,17 @@ export default function createHandler<
174
174
private handlerTag : number ;
175
175
private config : Record < string , unknown > ;
176
176
private propsRef : React . MutableRefObject < unknown > ;
177
+ private isMountedRef : React . MutableRefObject < boolean | null > ;
177
178
private viewNode : any ;
178
179
private viewTag ?: number ;
179
- private updateEnqueued : ReturnType < typeof setImmediate > | null = null ;
180
180
private inspectorToggleListener ?: EmitterSubscription ;
181
181
182
182
constructor ( props : T & InternalEventHandlers ) {
183
183
super ( props ) ;
184
184
this . handlerTag = getNextHandlerTag ( ) ;
185
185
this . config = { } ;
186
186
this . propsRef = React . createRef ( ) ;
187
+ this . isMountedRef = React . createRef ( ) ;
187
188
this . state = { allowTouches } ;
188
189
if ( props . id ) {
189
190
if ( handlerIDToTag [ props . id ] !== undefined ) {
@@ -195,6 +196,7 @@ export default function createHandler<
195
196
196
197
componentDidMount ( ) {
197
198
const props : HandlerProps < U > = this . props ;
199
+ this . isMountedRef . current = true ;
198
200
199
201
if ( DEV_ON_ANDROID ) {
200
202
this . inspectorToggleListener = DeviceEventEmitter . addListener (
@@ -209,11 +211,10 @@ export default function createHandler<
209
211
// If there are unresolved refs (e.g. ".current" has not yet been set)
210
212
// passed as `simultaneousHandlers` or `waitFor`, we enqueue a call to
211
213
// _update method that will try to update native handler props using
212
- // setImmediate . This makes it so update() function gets called after all
214
+ // queueMicrotask . This makes it so update() function gets called after all
213
215
// react components are mounted and we expect the missing ref object to
214
216
// be resolved by then.
215
- this . updateEnqueued = setImmediate ( ( ) => {
216
- this . updateEnqueued = null ;
217
+ queueMicrotask ( ( ) => {
217
218
this . update ( UNRESOLVED_REFS_RETRY_LIMIT ) ;
218
219
} ) ;
219
220
}
@@ -239,11 +240,9 @@ export default function createHandler<
239
240
240
241
componentWillUnmount ( ) {
241
242
this . inspectorToggleListener ?. remove ( ) ;
243
+ this . isMountedRef . current = false ;
242
244
RNGestureHandlerModule . dropGestureHandler ( this . handlerTag ) ;
243
245
scheduleFlushOperations ( ) ;
244
- if ( this . updateEnqueued ) {
245
- clearImmediate ( this . updateEnqueued ) ;
246
- }
247
246
// We can't use this.props.id directly due to TS generic type narrowing bug, see https://github.com/microsoft/TypeScript/issues/13995 for more context
248
247
const handlerID : string | undefined = this . props . id ;
249
248
if ( handlerID ) {
@@ -367,14 +366,17 @@ export default function createHandler<
367
366
} ;
368
367
369
368
private update ( remainingTries : number ) {
369
+ if ( ! this . isMountedRef . current ) {
370
+ return ;
371
+ }
372
+
370
373
const props : HandlerProps < U > = this . props ;
371
374
372
375
// When ref is set via a function i.e. `ref={(r) => refObject.current = r}` instead of
373
376
// `ref={refObject}` it's possible that it won't be resolved in time. Seems like trying
374
377
// again is easy enough fix.
375
378
if ( hasUnresolvedRefs ( props ) && remainingTries > 0 ) {
376
- this . updateEnqueued = setImmediate ( ( ) => {
377
- this . updateEnqueued = null ;
379
+ queueMicrotask ( ( ) => {
378
380
this . update ( remainingTries - 1 ) ;
379
381
} ) ;
380
382
} else {
0 commit comments