[Web] Do not detach gestures from other detectors#4286
Open
m-bert wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a web-specific v3 reattach scenario where moving a single gesture instance between GestureDetectors could eventually stop working and crash due to one detector detaching a handler that had already been rebound by another detector. The approach mirrors a native-like ownership model on web by associating an attached handler with the “host detector” and only allowing that host to detach it.
Changes:
- Introduces a
HostDetectorref type and threads it through web handler initialization to track which detector currently owns a handler binding. - Updates the web
HostGestureDetectorto pass itsviewRefas the host identity when attaching and detaching handlers, preventing old detectors from tearing down new bindings. - Extends
NodeManager/RNGestureHandlerModule.webdetach/attach APIs to accept the host identity and apply ownership checks.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-gesture-handler/src/web/tools/NodeManager.ts | Adds host-aware detachment to avoid detaching handlers owned by another detector. |
| packages/react-native-gesture-handler/src/web/interfaces.ts | Defines HostDetector type used as the detector ownership identity. |
| packages/react-native-gesture-handler/src/web/handlers/RotationGestureHandler.ts | Threads hostDetector through handler init override. |
| packages/react-native-gesture-handler/src/web/handlers/PinchGestureHandler.ts | Threads hostDetector through handler init override. |
| packages/react-native-gesture-handler/src/web/handlers/NativeViewGestureHandler.ts | Threads hostDetector through handler init override. |
| packages/react-native-gesture-handler/src/web/handlers/LongPressGestureHandler.ts | Threads hostDetector through handler init override. |
| packages/react-native-gesture-handler/src/web/handlers/IGestureHandler.ts | Extends the web handler interface with hostDetectorView and a typed init signature. |
| packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts | Stores host detector identity on init to support ownership-based detach decisions. |
| packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.web.tsx | Passes a stable viewRef as both observation owner and detach/attach host identity. |
| packages/react-native-gesture-handler/src/RNGestureHandlerModule.web.ts | Extends attachGestureHandler/detachGestureHandler signatures to accept host identity on web. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Skip handler.detach() when the handler isn't attached, so a repeated detachGestureHandler is a safe no-op instead of re-running delegate cleanup on an already-cleared view (which would throw). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
j-piasecki
approved these changes
Jun 26, 2026
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.
Description
Fixes reattaching a v3 gesture between GestureDetectors on web. Moving a gesture from one detector to another would, after a cycle or two, stop working and then crash with Expected delegate view to be HTMLElement.
On web a gesture handler is shared per handler tag, so during a reattach both the old and the new detector touch the same handler. The new detector binds the handler to its view, but the old detector's cleanup then ran an unconditional detach — tearing down the binding the new detector had just established (and eventually calling detach on an already-cleared view, which threw). This mirrors the native ownership model on web.
Test plan
Tested on the following code: