From 487802b528b21dcf21aeee9fc40ce2e2cf9aab9c Mon Sep 17 00:00:00 2001 From: Charles Mangwa Date: Wed, 21 Aug 2024 12:21:08 +0200 Subject: [PATCH] fix: patch race condition when calling a modalfy method as the callback of another modalfy method Fixes #147. --- src/lib/StackItem.tsx | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/lib/StackItem.tsx b/src/lib/StackItem.tsx index af9f34a..ba1bc46 100644 --- a/src/lib/StackItem.tsx +++ b/src/lib/StackItem.tsx @@ -28,6 +28,15 @@ type Props

= SharedProps

& { pendingClosingAction?: ModalPendingClosingAction } +const addCallbackToMacroTaskQueue = (fn: (() => void) | undefined) => { + if (typeof fn === 'function') { + const timeout = setTimeout(() => { + clearTimeout(timeout) + fn?.() + }, 0) + } +} + const StackItem =

({ stack, zIndex, @@ -115,24 +124,24 @@ const StackItem =

({ const updateAnimatedValue = useCallback( ( toValue: number, - closeModalCallback?: (closingElement: ModalStackItem

) => void, - modalStackItemCallback?: () => void, + internalClosingCallback?: (closingElement: ModalStackItem

) => void, + stackItemCallback?: () => void, ) => { - if (!closeModalCallback && animationIn) { - animationIn(animatedValue, toValue, modalStackItemCallback) - } else if (closeModalCallback && animationOut) { + if (!internalClosingCallback && animationIn) { + animationIn(animatedValue, toValue, stackItemCallback) + } else if (internalClosingCallback && animationOut) { animationOut(animatedValue, toValue, () => { - closeModalCallback(stackItem) - modalStackItemCallback?.() + internalClosingCallback(stackItem) + addCallbackToMacroTaskQueue(stackItemCallback) }) } else { Animated.timing(animatedValue, { toValue, useNativeDriver: true, - ...(closeModalCallback ? animateOutConfig : animateInConfig), + ...(internalClosingCallback ? animateOutConfig : animateInConfig), }).start(() => { - closeModalCallback?.(stackItem) - modalStackItemCallback?.() + internalClosingCallback?.(stackItem) + addCallbackToMacroTaskQueue(stackItemCallback) }) } }, @@ -147,7 +156,7 @@ const StackItem =

({ onCloseListener.current({ type: 'closeModal', origin: wasClosedByBackdropPress ? 'backdrop' : 'default' }) closeModal(modalName) if (pendingClosingAction?.action === 'closeModal') removeClosingAction(pendingClosingAction) - if (typeof callback === 'function') callback?.() + addCallbackToMacroTaskQueue(callback) }) }, [ @@ -170,7 +179,7 @@ const StackItem =

({ onCloseListener.current({ type: 'closeModals', origin: 'default' }) let output = closeModals(closingElement) if (pendingClosingAction?.action === 'closeModals') removeClosingAction(pendingClosingAction) - if (typeof callback === 'function') callback?.() + addCallbackToMacroTaskQueue(callback) return output }) }, @@ -185,7 +194,7 @@ const StackItem =

({ onCloseListener.current({ type: 'closeAllModals', origin: wasClosedByBackdropPress ? 'backdrop' : 'default' }) closeAllModals() if (pendingClosingAction?.action === 'closeAllModals') removeClosingAction(pendingClosingAction) - if (typeof callback === 'function') callback?.() + addCallbackToMacroTaskQueue(callback) }) }, [closeAllModals, hideBackdrop, pendingClosingAction, position, updateAnimatedValue, wasClosedByBackdropPress],