Skip to content

[Bug]: Closed modal with enableDismissOnClose={false} reopens when another modal is dismissed #2795

Open

Description

@Glenn444

Version

v5 (@gorhom/bottom-sheet 5.2.14, also current master)

Reanimated Version

v4 (react-native-reanimated 4.5.1, react-native-worklets 0.10.1; the template only lists v3)

Gesture Handler Version

v2 (2.32.0)

Platforms

Android (tested on a real device in Expo Go SDK 57, and in a release build of our app). The faulty logic is in JS, so iOS should behave the same.

What happened?

A BottomSheetModal with enableDismissOnClose={false} that has been closed (index -1) opens again by itself after a second modal is presented and then dismissed.

This is the second scenario in #1561 ("close first modal → open second → close second → first reopens"). That issue was closed in 2024, but this still happens on 5.2.14. It is not the same bug as #2765 (that one is a modal that is still animating closed, with the default enableDismissOnClose) and it is not fixed by #2698: I applied #2698 alone and A still reopens.

Root cause. With enableDismissOnClose={false}, a closed modal stays mounted and stays in the provider's queue with status CLOSED. When the next modal is presented, the provider (switch behaviour) calls minimize() on it. In handleMinimize, currentIndexRef.current === -1 is read as "minimized before it finished its mounting animation", so the index prop is saved as the restore point and the status becomes MINIMIZING. When the next modal is dismissed, the provider calls restore(), which runs snapToIndex(index), and the modal the user closed opens.

Instrumented trace from a release build (modal A = bottom-sheet-modal-2, B = bottom-sheet-modal-4):

onChange  A to=-1                       (A closed → status CLOSED)
mountSheet B, switch, queue=[A]
minimize  A status=2 (CLOSED) cur=-1    → restoreIndex = index prop (0), status = MINIMIZING
handleWillUnmountSheet B
restore   A status=4 (MINIMIZING) restoreIndex=0
onChange  A to=0                        ← A opens again

Suggested fix (PR to follow): in handleMinimize, treat a CLOSED modal as having nothing to minimize, and make restore() a no-op when there is no restore index. A modal minimized while open is not affected.

Results on a real device with the Snack below:

Library Closed A, then B shown and dismissed Open A, then B shown and dismissed
5.2.14 A reopens ✗ A is not restored ✗ (#2788 / #2685)
5.2.14 + suggested fix A stays closed ✓ A is not restored (unchanged)
5.2.14 + #2698 A reopens ✗ A is restored ✓
5.2.14 + #2698 + suggested fix A stays closed ✓ A is restored ✓

Reproduction steps

  • Modal A: enableDismissOnClose={false}, snapPoints={['40%']}, default stackBehavior (switch).
  • Modal B: defaults, snapPoints={['25%']}.
  • Tap 1. Present A: A opens.
  • Tap 2. Close A: A closes (onChange -1).
  • Tap 3. Present B: B opens.
  • Tap 4. Dismiss B: B closes, and A opens again (A onChange 0), with no user action on A.

Expected: A stays closed.

Reproduction sample

https://snack.expo.dev/a2g2T79TyuloUkrflGrG9

Relevant log output

> 1. Present A
A onChange 0
> 2. Close A
A onChange -1
> 3. Present B
B onChange 0
> 4. Dismiss B
A onChange 0
B onChange -1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions