Skip to content

fix: gesture not activating due to outdated handler tag #3578

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hannojg
Copy link

@hannojg hannojg commented Jun 26, 2025

Description

This fixes an issue where the manual activation of a handler wouldn't work.
I unfortunately didn't had time to make a full reproduction. The scenario roughly looks like this:

const gesture = useMemo(() -> Gesture.Pan() // Note happens also without useMemo
	.manualActivation(true)
	.onTouchesMove((event, manager) => {
			// Some criteria to met:
			manager.activate()
	})
	.onUpdate(() => {
		// Wouldn't get called on a remount
	})

return <GestureDetector gesture={gesture}> // ...

This is being used in a component on a screen. When we navigate from the screen the component gets unmounted and I can see that his logic is being triggered:

useLayoutEffect(() => {
const viewTag = findNodeHandle(state.viewRef) as number;
preparedGesture.isMounted = true;
attachHandlers({
preparedGesture,
gestureConfig,
gesturesToAttach,
webEventHandlersRef,
viewTag,
});
return () => {
preparedGesture.isMounted = false;
dropHandlers(preparedGesture);
};
}, []);

attachHandler 1
dropHandler 1

I think the screen might get frozen instead of unmounted, but not entirely sure, but the cleanup function gets called and the handler gets dropped.
Now, when reopening the screen the handlers will reattach, but have a different handler tag now.

attachHandler 1
dropHandler 1
attachHandler 2 

When I now run the gesture I can see that the manager still has the previous handler tag, and thus on the native side it can't find the handler to activate. Its calling setGestureHandlerState(1 /* previous id */) here (when I call manager.activate):

I found that attaching the handler tag to the GestureStateMangaer and recreating it if it has changed fixes the issue.
If you need a full reproduction to proceed with this change I can understand, just let me know then I can try to find time to create one 👍

Test plan

Well, shamefully I didn't create a reproduction so I guess the test plan is "trust me bro" 😅 not the best I know - sorry.

@hannojg
Copy link
Author

hannojg commented Jun 26, 2025

note: we only started observing this change after switching to new arch

@m-bert
Copy link
Contributor

m-bert commented Jun 27, 2025

Hi @hannojg! Thanks for spotting this issue and submitting a PR! It would be great if you could prepare a small reproduction 😅
Also, could you mark handlerTag inside manager as internal?

@m-bert
Copy link
Contributor

m-bert commented Jun 27, 2025

I can see that CI fails, could you also update gestureStateManager.web.ts file?

image

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.

2 participants