Skip to content

Fix Reanimated subscriptions when replacing a mounted gesture - #4634

Merged
m-bert merged 1 commit into
software-mansion:mainfrom
Elehiggle:codex/fix-reanimated-detector-events
Oct 27, 2026
Merged

m-bert merged 1 commit into
software-mansion:mainfrom
Elehiggle:codex/fix-reanimated-detector-events

Conversation

@Elehiggle

Copy link
Copy Markdown
Contributor

Description

Replacing one worklet gesture with another on a mounted GestureDetector leaves the new gesture's callbacks disconnected. NativeEventsManager retains the component object created on mount, but its props still points to the first set of worklet handlers. Later updateEvents calls therefore compare against stale props, and cleanup also reads that initial set.

Expose the latest committed worklet props through a getter on the retained object. Update the ref before calling updateEvents, so Reanimated can replace subscriptions while preserving the detector and its children. Set the current props and clear the previous props when the manager starts, including when React reconnects effects after an Activity becomes visible.

The regression uses Reanimated's real NativeEventsManager with mocked worklet-handler registration methods. It covers repeated replacements, handler addition/removal, unchanged handlers, child state, and cleanup on unmount. React Activity tests also check that revealing a detector attaches its current handler exactly once.

The standalone reproduction switches between two worklet pans on a retained detector and includes a remount control.

Test plan

  • Android 16 / API 36 x86_64 emulator, Fabric and Hermes, React Native 0.88.0, Reanimated 4.7.1, Worklets 0.13.0: the standalone example fails on v3.4.0 and main. After selecting B and dragging, both B counters remain zero; remounting enables B. With this patch, B receives begin/update events without a remount. iOS has not been tested.
  • On v3.4.0 (ff34dbf), three tests fail: replacement, addition, and duplicate registration when a previously visible Activity is revealed. With the fix, all five pass. Main (a83496b) has the same detector source.
  • yarn workspace react-native-gesture-handler test --runInBand: 238 tests pass across 24 suites.
  • Package ts-check, lint-js, and circular-dependency-check pass. Existing lint/dependency warnings remain.

Expose committed handler props to the retained NativeEventsManager before updating subscriptions. Reset previous props when effects attach again so Activity visibility changes do not leave stale or duplicate registrations.

Add regression coverage for handler replacement, addition and removal, retained children, cleanup, and Activity reconnection.
Copilot AI balanced review requested due to automatic review settings October 23, 2026 10:47
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9dff9540-b2fb-455b-9001-5bff7e248bbb
📥 Commits

Reviewing files that changed from the base of the PR and between a83496b and b1889fa.

📒 Files selected for processing: 2
  • packages/react-native-gesture-handler/src/__tests__/reanimatedNativeDetector.test.tsx
  • packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Improved native gesture handling when event handlers are replaced or removed, helping preserve the detector and child state.
    • Ensured handlers remain active when unchanged and register correctly when a previously hidden activity becomes visible.
  • Tests
    • Added coverage for handler updates, removal, and visibility changes to help verify consistent gesture behavior.

LeanReanimatedNativeDetector now provides its native event manager with current props through a ref-backed getter. Tests cover event-handler registration and cleanup across prop changes and hidden Activity states.

Changes: Reanimated detector prop updates

Layer / File(s) Summary
Current props and handler registration
packages/react-native-gesture-handler/src/v3/detectors/ReanimatedNativeDetector.tsx, packages/react-native-gesture-handler/src/__tests__/reanimatedNativeDetector.test.tsx
The detector refreshes its props ref during setup and prop updates. Tests cover handler replacement, removal, unchanged handlers, host and child state, and registration after a hidden Activity is revealed.

Suggested reviewers: j-piasecki

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to b1889

The handler replacement and Activity reveal paths appear ready to merge after normal checks.

Pre-merge checks: Passed 3
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: fixing Reanimated subscriptions when a mounted gesture is replaced.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused lifecycle fix and regression coverage address the stale subscriptions without identified blocking issues; tests were not independently executed.

No open issues 🎉

What changed in this PR

Fixes Reanimated subscriptions when worklet gestures change on a mounted v3 detector, preserving the detector and its child state.

Changes:

  • Exposes the latest committed handler props to Reanimated’s retained event manager.
  • Resets subscription bookkeeping when effects reconnect, including React Activity reveals.
  • Adds regression tests for handler replacement, addition/removal, unchanged handlers, state preservation, and cleanup.
File Description
packages/​react-native-gesture-handler/​src/​v3/​detectors/​ReanimatedNativeDetector.tsx Keeps event-manager props current and resets previous props on effect setup.
packages/​react-native-gesture-handler/​src/​__tests__/​reanimatedNativeDetector.test.tsx Tests subscription updates and lifecycle behavior using Reanimated’s real event manager.

Review effort: Balanced

@m-bert m-bert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing this!

@m-bert
m-bert merged commit f9350ca into software-mansion:main Oct 27, 2026
11 checks passed
@Elehiggle
Elehiggle deleted the codex/fix-reanimated-detector-events branch October 28, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants