react-doctor/rn-prefer-pressable
Use `<Pressable>` from react-native (or react-native-gesture-handler) instead of legacy Touchable* components
- Category: React Native
- Severity: warn
- Source:
oxlint-plugin-react-doctor - Framework: react-native
- Enabled when: framework=react-native and capabilities=react-native
Validation prompt
Use this to decide whether a fired diagnostic is real or a false positive.
The rule fires on an ImportSpecifier from "react-native" whose imported name is TouchableOpacity, TouchableHighlight, TouchableWithoutFeedback, or TouchableNativeFeedback. The JSX usage itself isn't analysed. False positive: a very old RN target where Pressable's Android ripple parity was incomplete — rare today since Pressable has been stable since 0.63.
Fix prompt
Use this once validation confirms the diagnostic is real.
Swap the legacy component for Pressable from react-native and move opacity or ripple feedback into the style callback (style={({ pressed }) => ...}) or the android_ripple prop. For complex gestures such as simultaneous pan plus long-press, use GestureDetector with Gesture.Tap() from react-native-gesture-handler instead. See https://reactnative.dev/docs/pressable
Related rules
More React Native rules from the rules reference:
react-doctor/rn-prefer-pressable-over-gesture-detector: Replace tap-only `<GestureDetector>` with `<Pressable>`: <Pressable onPress={onPress}> or createCSSAnimatedComponent(Pressable) for animated press feedbackreact-doctor/rn-prefer-reanimated: Use `import Animated from 'react-native-reanimated'` — animations run on the UI thread instead of the JS threadreact-doctor/rn-pressable-shared-value-mutation: Wrap in <GestureDetector gesture={Gesture.Tap()...}> so the press animation runs on the UI thread instead of bouncing across the JS bridgereact-doctor/rn-scrollview-dynamic-padding: Use `contentInset={{ bottom: dynamicValue }}` — the OS applies it as an offset without reflowing the scroll contentreact-doctor/rn-scrollview-flex-in-content-container: Replace `flex: <positive number>` on contentContainerStyle with `flexGrow: 1`