feat: only the last mounted OverlayProvider handles open events#220
Open
feat: only the last mounted OverlayProvider handles open events#220
Conversation
When multiple OverlayProvider instances share the same overlay context, all providers previously received open events causing duplicate renders. Each provider now tracks its mount order and only the most recently mounted instance handles open events, falling back to the previous provider when it unmounts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@manNomi is attempting to deploy a commit to the Toss Team on Vercel. A member of the Team first needs to authorize it. |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When multiple OverlayProvider instances share the same overlay context, all providers previously received open events causing duplicate renders.
Each provider now tracks its mount order and only the most recently mounted instance handles open events, falling back to the previous provider when it unmounts.
Description
When using navigation stacks (e.g. Stackflow, React Navigation), mounting multiple
OverlayProviderinstances caused all providers to subscribe to the same event channel, resulting in duplicate overlay renders onoverlay.open().This PR fixes the issue by maintaining a module-level stack of mounted providers, ensuring only the most recently mounted provider handles open events. When that provider unmounts, the previous one automatically becomes active again.
Related Issue: Fixes # (issue_number)
Changes
mountedInstancesstack to track mounted provider instancesMotivation and Context
In navigation stack environments, it's common to mount multiple
OverlayProviderinstances per activity or screen to achieve isolated overlay scopes. However, since all providers shared the same event channel, callingoverlay.open()triggered renders in every mounted provider simultaneously.The only workaround was wrapping
experimental_createOverlayContextin a React Context manually, which added boilerplate and relied on an experimental API. This change makes scoped overlay handling work correctly out of the box without any extra setup.How Has This Been Tested?
ProviderA→ProviderBin sequence and verified onlyProviderBhandlesoverlay.open()ProviderBand verifiedProviderAcorrectly becomes active and handles subsequentoverlay.open()callsScreenshots (if appropriate):
Before:
overlay.open()triggers renders in all mounted providersAfter: Only the most recently mounted provider renders the overlay
Types of changes
Checklist
Further Comments
This PR was inspired by #221.
It's intended as a lightweight, directional proposal rather than a complete implementation — I'd really appreciate any feedback or thoughts on whether this is the right approach. If there's a preferred direction or existing plan for handling this, I'd love to know!
Regardless of the implementation approach, I strongly believe that triggering
overlay.open()across all mounted providers simultaneously is a bug rather than intended behavior. There is no practical use case where a user would expect a singleopen()call to render overlays in every provider at once — especially in a navigation stack context where each screen should manage its own overlay scope independently.Known trade-off:
close,unmount,closeAll, andunmountAllstill dispatch to all providers, creating an asymmetry withopen. If this is a concern, an opt-in prop (e.g.<OverlayProvider exclusive>) could be considered as an alternative approach.The previous workaround using
experimental_createOverlayContextwrapped in a React Context still works and is not affected by this change. This fix addresses the root cause at the provider level so users no longer need to implement the pattern manually.