Skip to content

[General] Only overwrite ref if the dropped handler didn't change#3984

Merged
j-piasecki merged 1 commit into
mainfrom
@jpiasecki/fix-ref-override
Feb 19, 2026
Merged

[General] Only overwrite ref if the dropped handler didn't change#3984
j-piasecki merged 1 commit into
mainfrom
@jpiasecki/fix-ref-override

Conversation

@j-piasecki
Copy link
Copy Markdown
Member

Description

It's possible that when a gesture is updated, the new values in the ref will be overwritten after being updated, due to the cleanup not checking what it's deleting.

It was possible to get this scenario:

 LOG  useGesture createGestureHandler TapGestureHandler 1 previous  -1
 LOG  useGesture useEffect TapGestureHandler 1
 LOG  useGesture createGestureHandler TapGestureHandler 2 previous TapGestureHandler 1
 LOG  useGesture useEffect cleanup TapGestureHandler 1
 LOG  useGesture createGestureHandler TapGestureHandler 2 previous  -1

where the last update would crash due to the ref being cleared by the cleanup of TapGestureHandler 1 AFTER being updated by TapGestureHandler 2.

Test plan

File 1:

import React from 'react';
import { View } from 'react-native';
import { GestureDetector, useTapGesture } from 'react-native-gesture-handler';

function Test() {
  const gesture = useTapGesture({
    onActivate: () => {
      console.log('onActivate');
    },
  });

  const COMMENT_THIS_FIRST = 2;

  return (
    <GestureDetector gesture={gesture}>
      <View style={{ width: 100, height: 100, backgroundColor: 'red' }} />
    </GestureDetector>
  );
}

export default Test;

File2:

import React from 'react';
import { GestureHandlerRootView } from 'react-native-gesture-handler';

import Test from './File1';

function Example() {
  let COMMENT_THIS_SECOND = 1;

  return (
    <GestureHandlerRootView>
      <Test />
    </GestureHandlerRootView>
  );
}

export default Example;

Comment out COMMENT_THIS_FIRST, save, then comment out COMMENT_THIS_SECOND and save.

Copilot AI review requested due to automatic review settings February 18, 2026 16:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a race where an outdated useEffect cleanup could clear currentGestureRef after a newer handler updated it, leading to erroneous re-creation and potential crashes during rapid updates (e.g., React Refresh / fast updates).

Changes:

  • Guard currentGestureRef cleanup so it only resets the ref when the ref still points at the handler being dropped.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Member

@tomekzaw tomekzaw left a comment

Choose a reason for hiding this comment

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

I've tried this PR in my app and it fixes the bug. Thanks!

@j-piasecki j-piasecki merged commit 35cb78c into main Feb 19, 2026
9 checks passed
@j-piasecki j-piasecki deleted the @jpiasecki/fix-ref-override branch February 19, 2026 09:07
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.

4 participants