TextInput claims the responder on every selection change, even with no active touch
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- C++
- Sterne
- 127k
- Forks
- 25.3k
- Ø Merge
- 1 T. 23 Std.
- Gemergte PRs (30 T.)
- 4
Beschreibung
Description
Where: Libraries/Components/TextInput/TextInput.js, onSelectionChangeShouldSetResponder={emptyFunctionThatReturnsTrue} (line 607 on main today), with {...otherProps} spread before it so a caller cannot override.
What happens: the claim exists for drag-selection with a finger down, but it fires for every selection change the plugin walks, including ones caused by typing, whenever the plugin's touch counter is above zero (see https://github.com/react/react/issues/37571 for how that counter drifts). The focused input then holds the JS responder with no touch active, and the next tap outside it is dropped.
Fix: claim only while event.touchHistory.numberActiveTouches > 0, and let a caller pass their own onSelectionChangeShouldSetResponder. Verified in an app patch on RN 0.85.3.
Proposed change (against main, packages/react-native/Libraries/Components/TextInput/TextInput.js, line 607 in InternalTextInput). Claim only while there is an active touch, and let a caller override:
onSelectionChange={_onSelectionChange}
- onSelectionChangeShouldSetResponder={emptyFunctionThatReturnsTrue}
+ // The claim exists for drag-selection with a finger down. Typing
+ // also changes the selection, and with no touch active the input
+ // must not take the responder, or the next tap outside it is dropped.
+ onSelectionChangeShouldSetResponder={
+ props.onSelectionChangeShouldSetResponder ??
+ (e => (e?.touchHistory?.numberActiveTouches ?? 0) > 0)
+ }
selection={selection}
The same line appears once more in the Android branch of the same file. We run this in production through patch-package against React Native 0.85.3.
Steps to reproduce
As described above
React Native Version
0.85.3
Affected Platforms
Runtime - iOS
Output of npx @react-native-community/cli info
System:
OS: macOS 26.5.1
CPU: (12) arm64 Apple M2 Max
Memory: 264.73 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 24.11.0
path: /Users/michaelsageryd/.nvm/versions/node/v24.11.0/bin/node
Yarn: Not Found
npm:
version: 11.3.0
path: /Users/michaelsageryd/dev/plantrail/client/plantrail_mobile/node_modules/.bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.16.2
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.5
- iOS 26.5
- macOS 26.5
- tvOS 26.5
- visionOS 26.5
- watchOS 26.5
Android SDK:
API Levels:
- "31"
- "35"
- "36"
- "36"
Build Tools:
- 35.0.0
- 36.0.0
- 36.1.0
- 37.0.0
System Images:
- android-36 | Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2025.3 AI-253.32098.37.2534.15232325
Xcode:
version: 26.6/17F113
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.18
path: /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/javac
Ruby:
version: 3.4.7
path: /opt/homebrew/opt/ruby@3.4/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.1.0
wanted: 20.1.0
react:
installed: 19.2.3
wanted: 19.2.3
react-native:
installed: 0.85.3
wanted: ^0.85.3
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
No trace
MANDATORY Reproducer
Reproducer: https://github.com/facebook/react-native/pull/58449
Screenshots and Videos
No response
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne in packages/react-native/Libraries/Components/TextInput/TextInput.js bei den beiden Vorkommen von onSelectionChangeShouldSetResponder in InternalTextInput und prüfe anschließend den obligatorischen Reproducer PR #58449. Bestätige, dass beide Zweige die angeforderte Touch-History-Bedingung und die Überschreibung durch den Aufrufer unterstützen. Erledigt ist es, wenn Auswahländerungen ohne aktiven Touch nicht den Responder beanspruchen, während die Auswahl per Ziehen dies weiterhin kann und Aufrufer ihren eigenen Handler bereitstellen können.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- javascript, react-native
- Bereich
- mobile, mobile-dev
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 74/100