iOS: Multiline TextInput onKeyPress event handler unexpectedly receives a Backspace event
Description
The TextInput onKeyPress event handler receives an unexpected Backspace event when multiline is true. The exact behavior varies between iOS 15 and iOS 16:
-
iOS 15: The
Backspaceevent is received aftervalueis reset to an empty string -
iOS 16: The
Backspaceevent is received on EVERY change AND whenvalueis reset to an empty string
This has been tested on iOS 15.5, 16.4, and 16.5.
Possibly related: https://github.com/facebook/react-native/issues/34891
React Native Version
0.71.11
Output of npx react-native info
System: OS: macOS 13.4 CPU: (16) x64 Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz Memory: 27.38 GB / 64.00 GB Shell: 5.9 - /usr/local/bin/zsh Binaries: Node: 18.16.0 - ~/.asdf/installs/nodejs/18.16.0/bin/node Yarn: 1.22.19 - /usr/local/bin/yarn npm: 9.6.6 - ~/.asdf/plugins/nodejs/shims/npm Watchman: Not Found Managers: CocoaPods: 1.12.1 - /Users/jeff/.asdf/shims/pod SDKs: iOS SDK: Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4 Android SDK: Not Found IDEs: Android Studio: 2022.2 AI-222.4459.24.2221.10121639 Xcode: 14.3.1/14E300c - /usr/bin/xcodebuild Languages: Java: 11.0.13 - /Users/jeff/.asdf/shims/javac npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.11 => 0.71.11 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found
Steps to reproduce
- Add a
<TextInput multiline />component and log all events received byonKeyPress - Type into the input
- Observe that an event with
nativeEvent.keyset to'Backspace'is received after everyonKeyPressevent is received for the typed key
Snack, code example, screenshot, or link to a repository
https://github.com/jbrowning/RN071TextInputBackspace
Same issue here
Cc: @NickGerleman
I'm having the same issue on iOS 16.4 with a single line textfield.
<TextInput onKeyPress={(e) => console.log(e.nativeEvent} />
Pressing a random key, such as 'a' results in the following log:
{"eventCount": 1, "key": "a", "target": 1205}
{"eventCount": 2, "key": "Backspace", "target": 1205}
I'm guessing it's related to iOS 16.4, because some of my components that were working before are now broken
My current clunky workaround is to check for the distance between events, under 100 milliseconds I ignore the Backspace:
function onKeyPress(e) {
if (e.nativeEvent.key === 'Backspace' && Date.now() - latestTimestamp > 100) {
// Handle backspace actually wanted by the user
}
if (e.nativeEvent.key !== 'Backspace') {
latestTimestamp = Date.now()
}
}
I'm also having this problem on a physical iPhone 11 Pro running iOS 16.1.1. My project is using Expo. The behaviour does not occur on Android.
I have the same issue, after each key press event of the TextInput component, I have a Backspace.
LOG F
LOG Backspace
React Native: 0.71.6 IOS: 16.4
We also seem to get duplicated Enter key presses.
System:
OS: macOS 13.5.2
CPU: (8) arm64 Apple M1 Pro
Memory: 95.41 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.16.1 - ~/.nvm/versions/node/v18.16.1/bin/node
Yarn: Not Found
npm: 9.5.1 - ~/.nvm/versions/node/v18.16.1/bin/npm
Watchman: 2023.07.03.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.12.1 - /Users/tibbe/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms: DriverKit 23.0, iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0
Android SDK: Not Found
IDEs:
Android Studio: 2022.2 AI-222.4459.24.2221.10121639
Xcode: 15.0/15A240d - /usr/bin/xcodebuild
Languages:
Java: 11.0.19 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.2.0 => 18.2.0
react-native: 0.71.13 => 0.71.13
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
Same issue here, but with multiline = false. And also I hit on return key in my iOS simulator, it does not show any event
same here in 0.72.7 version
I experience the same issue React Native: 0.70.10 iOS: 17.2, simulator
I am still experiencing this issue.
iOS 17.4.1 , iPhone 11 React Native: 0.73.6 Expo Managed Workflow Expo SDK: 50.0.14
Has anyone got more information or found a way around this problem?
I am also experiencing this issue
I am facing this issue also
still running into this issue as of react native 0.74.2 on iOS
Just a note on a workaround we've been using: we wrap our TextInput so that we ignore all backspaces within 50 ms. of another keypress:
import { NativeSyntheticEvent, TextInput, TextInputProps, TextInputKeyPressEventData } from 'react-native';
function OurTextInput(props: TextInputProps) {
const { onKeyPress } = props;
const latestNonBackspaceKeyPressMsRef = useRef<number | null>(null);
const handleKeyPress = useCallback((e: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
if (!onKeyPress) {
return;
}
// This is a workaround for a bug where the react native text input
// registers a Backspace key press after every other keypress
//
// documented here:
// https://github.com/facebook/react-native/issues/37967
if (e.nativeEvent.key === 'Backspace') {
if (
!latestNonBackspaceKeyPressMsRef.current ||
Date.now() - latestNonBackspaceKeyPressMsRef.current > 80
) {
onKeyPress(e);
}
} else {
latestNonBackspaceKeyPressMsRef.current = Date.now();
onKeyPress(e);
}
}, [onKeyPress]);
return <TextInput {...props} onKeyPress={handleKeyPress} />
}