diff --git a/packages/react-native-gesture-handler/src/v3/components/PressableWithTouchable.tsx b/packages/react-native-gesture-handler/src/v3/components/PressableWithTouchable.tsx index e80c389670..923cc61ab6 100644 --- a/packages/react-native-gesture-handler/src/v3/components/PressableWithTouchable.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/PressableWithTouchable.tsx @@ -98,7 +98,7 @@ const PressableWithTouchable = (props: PressableProps) => { } = rest; /* eslint-enable @typescript-eslint/no-unused-vars */ - const [pressed, setPressed] = useState(testOnly_pressed ?? false); + const [pressed, setPressed] = useState(false); const timers = useRef({ press: null, hoverIn: null, hoverOut: null }); const dimensions = useRef({ width: 0, height: 0 }); @@ -284,11 +284,18 @@ const PressableWithTouchable = (props: PressableProps) => { } : undefined; + // `testOnly_pressed` forces the pressed state for snapshots/tests. Derive the + // displayed value from it each render, keeping the interactive `pressed` state + // independent (seeded to false) so clearing the prop doesn't leave it stuck. + const displayPressed = testOnly_pressed ?? pressed; + const resolvedStyle = - typeof style === 'function' ? style({ pressed }) : style; + typeof style === 'function' ? style({ pressed: displayPressed }) : style; const resolvedChildren = - typeof children === 'function' ? children({ pressed }) : children; + typeof children === 'function' + ? children({ pressed: displayPressed }) + : children; return ( { ...remainingProps } = props; - const [pressedState, setPressedState] = useState(testOnly_pressed ?? false); + const [pressedState, setPressedState] = useState(false); const longPressTimeoutRef = useRef(null); const pressDelayTimeoutRef = useRef(null); @@ -400,12 +400,17 @@ const StatefulPressable = (props: PressableProps) => { const pointerStyle: StyleProp = Platform.OS === 'web' ? { cursor: 'pointer' } : {}; + // `testOnly_pressed` forces the pressed state for snapshots/tests. Derive the + // displayed value from it each render, keeping the interactive `pressedState` + // independent (seeded to false) so clearing the prop doesn't leave it stuck. + const displayPressed = testOnly_pressed ?? pressedState; + const styleProp = - typeof style === 'function' ? style({ pressed: pressedState }) : style; + typeof style === 'function' ? style({ pressed: displayPressed }) : style; const childrenProp = typeof children === 'function' - ? children({ pressed: pressedState }) + ? children({ pressed: displayPressed }) : children; const rippleColor = useMemo(() => {