Skip to content

[General] Allow explicit opt-in for the Animated codepaths when not using native driver - #3824

Merged
j-piasecki merged 6 commits into
nextfrom
@jpiasecki/explicit-animated-opt-in
Nov 20, 2025
Merged

j-piasecki merged 6 commits into
nextfrom
@jpiasecki/explicit-animated-opt-in

Conversation

@j-piasecki

Copy link
Copy Markdown
Member

Description

Currently, we're enabling the Animated codepath only when the handler passed to onUpdate is an Animated.Event with useNativeDriver. When useNativeDriver is not enabled, Animated.event returns a function, and we have no way of differentiating between it and a function passed by the user.

This is not ideal since the animated codepath receives events in a different format (wrapped with nativeEvent). This meant that the code would stop working when switching between using the native driver and not. The same would happen when trying to use a native driver in code supposed to also run on web, where it's not available - the gesture would work on mobile, but crash on web.

To avoid this, this PR adds an option to explicitly opt-in to the animated codepath by setting useAnimated in the gesture config. This will automatically disable Reanimated and throw an error when user if the user tries to reenable it.

Test plan

Tested on the Native Detector example in the basic app, as well as on the expo app on the same example for web.

@j-piasecki j-piasecki left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Let me know if you prefer the AnimatedEvent type fixes to be in a separate PR

Comment on lines +28 to +30
onUpdate?:
| ((event: GestureUpdateEvent<THandlerData>) => void)
| AnimatedEvent;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Instead of a function or an AnimatedEvent, it was a function that was returning void or AnimatedEvent.

This was irritating, as it was the reason types in InterceptingGestureDetector were correct.

Comment on lines +129 to +137
if (typeof gesture?.detectorCallbacks[key] === 'function') {
// @ts-expect-error passing event to a union of functions where only one is typed as such
gesture.detectorCallbacks[key](e);
}

virtualChildren.forEach((child) => {
const method = child.methods[key];
if (method) {
if (typeof method === 'function') {
// @ts-expect-error passing event to a union of functions where only one is typed as such

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Those types.

(key: keyof DetectorCallbacks<THandlerData>) => {
return (e: GestureHandlerEvent<THandlerData>) => {
if (gesture?.detectorCallbacks[key]) {
if (typeof gesture?.detectorCallbacks[key] === 'function') {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is also covering undefined check, typeof undefined === 'undefined'

Comment on lines +54 to 56
export type AnimatedEvent = {
_argMapping: (Animated.Mapping | null)[];
};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

After fixing the type above, this started breaking type inference and every onUpdate was being typed as (...any) => void

import { useReanimatedTouchEvent } from './callbacks/reanimated/useReanimatedTouchEvent';
import { tagMessage } from '../../utils';

function guardJSAnimatedEvent(handler: (...args: unknown[]) => void) {

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.

I'm not a fun of this name, but I cannot think of any better.

@j-piasecki
j-piasecki merged commit 1cf805a into next Nov 20, 2025
2 checks passed
@j-piasecki
j-piasecki deleted the @jpiasecki/explicit-animated-opt-in branch November 20, 2025 08:19
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