react-doctor/rn-no-panresponder
Replace PanResponder with react-native-gesture-handler's Gesture.Pan(), which runs gesture math on the native UI thread instead of the JS thread.
- Category: Bugs
- Severity: warn
- Source:
oxlint-plugin-react-doctor - Framework: react-native
- Enabled when: framework=react-native and capabilities=react-native
- Tags: react-native, test-noise
- Default: Enabled
Validation prompt
Use this to decide whether a fired diagnostic is real or a false positive.
Fires on an ImportDeclaration whose source is exactly "react-native" that has a non-type ImportSpecifier whose resolved imported name (getImportedName, so an alias like import { PanResponder as PR } still resolves to PanResponder) equals "PanResponder"; it reports each such specifier. The detector deliberately skips type-only imports (declaration-level import type { PanResponder } from "react-native" and inline import { View, type PanResponder } from "react-native") because they erase at build time. Suppress as a false positive when: PanResponder is imported from any source other than "react-native" (e.g. a local ./my-gestures module or a re-export), it is only a local binding such as const PanResponder = makeResponder(), or the import is type-only — none of these create a runtime JS-thread PanResponder.
Fix prompt
Use this once validation confirms the diagnostic is real.
Migrate the gesture off PanResponder to react-native-gesture-handler so it runs on the native UI thread: replace PanResponder.create({ onPanResponderMove, ... }) plus the spread {...panResponder.panHandlers} with a Gesture.Pan() configured via .onUpdate(e => ...)/.onEnd(...) and apply it through <GestureDetector gesture={pan}>, wrapping the tree in GestureHandlerRootView and driving position with Reanimated shared values for 60fps under JS load. Remove the now-unused PanResponder import from react-native.
Related rules
More Bugs rules from the rules reference:
react-doctor/rn-no-raw-text: Wrap text in a `<Text>` component: `<Text>{value}</Text>` — raw strings outside `<Text>` crash on React Nativereact-doctor/rn-no-renderitem-key: Remove the no-op `key` from the JSX row that renderItem returns and set `keyExtractor` (or `item.key`) on the list instead.react-doctor/rn-no-scroll-state: Track scroll position with a Reanimated shared value (`useAnimatedScrollHandler`) or a ref — `setState` on every scroll event causes re-render stormsreact-doctor/rn-no-scrollview-mapped-list: Use FlashList, LegendList, or FlatList — `<ScrollView>{items.map(...)}</ScrollView>` mounts every row in memoryreact-doctor/rn-no-set-native-props: Drive the prop via state, an Animated.Value (useNativeDriver: true), or a Reanimated shared value instead of imperative setNativeProps