react-native: TextInput cursor jump to right end when the input is empty (Android only)
Please provide all the information requested. Issues that do not follow this format are likely to stall.
Description
TextInput that has the placeholder
set, and styles with textAlign: "center"
and manages the value with useState
hook, makes the cursor jump to the end of the input field when we clear the contents with backspace.
import React, { useState } from "react";
import { StyleSheet, Text, View, TextInput } from "react-native";
export default function App() {
const [state, setState] = useState("");
return (
<View>
<Text>Open up App.tsx to start working on your app!</Text>
<TextInput
style={styles.input}
placeholder="My placeholder"
value={state}
onChangeText={setState}
></TextInput>
</View>
);
}
const styles = StyleSheet.create({
input: {
marginTop: 50,
backgroundColor: "yellow",
textAlign: "center",
width: "100%",
},
});
Related StackOverflow question: https://stackoverflow.com/questions/60276121/textinput-cursor-jump-to-right-end-when-the-input-is-empty
React Native version:
Run react-native info
in your terminal and copy the results here.
System: OS: macOS Mojave 10.14.6 CPU: (4) x64 Intel® Core™ i5-5257U CPU @ 2.70GHz Memory: 39.64 MB / 16.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 8.11.4 - ~/.nvm/versions/node/v8.11.4/bin/node Yarn: 1.9.4 - /usr/local/bin/yarn npm: 6.14.1 - ~/.nvm/versions/node/v8.11.4/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.9.1 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 13.1, DriverKit 19.0, macOS 10.15, tvOS 13.0, watchOS 6.0 Android SDK: API Levels: 28, 29 Build Tools: 28.0.3, 29.0.2 System Images: android-28 | Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom_64, android-28 | Google Play Intel x86 Atom, android-29 | Google APIs Intel x86 Atom Android NDK: Not Found IDEs: Android Studio: 3.5 AI-191.8026.42.35.6010548 Xcode: 11.1/11A1027 - /usr/bin/xcodebuild Languages: Java: 1.8.0_241 - /usr/bin/javac Python: 2.7.16 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: ~16.9.0 => 16.9.0 react-native: ~0.62 => 0.62.2 npmGlobalPackages: react-native: Not Found
Steps To Reproduce
Provide a detailed list of steps that reproduce the issue.
- Create an empty RN project
- Add the TextInput with the styles in the code above to the
App.tsx
file - Run the app on a Android device
- Click the text input (Cursor should be at the center)
- Type some text (Cursor should still be placed correctly)
- Hit backspace to clear the input (Now when the input is completely cleared the cursor jumps all the way to the right)
Some times, when listening to changes in dev mode to update the app, the faulty behaviour is not noticed at first. When that happens, I comment out the placeholder
prop and save for the app on my android emulator to refresh. Then I uncomment it again, and save to refresh one more time. With this I am able to reproduce the problem 100% of the time.
Expected Results
When the style textAlign: "center"
is set, the cursor should stay in the center after you clear the input.
Snack, code example, screenshot, or link to a repository:
Please select the Android platform on snack to see the problem https://snack.expo.io/QuGin01cF
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 6
- Comments: 25 (8 by maintainers)
Not sure why, but, setting multiline={true} fixed it for me
https://stackoverflow.com/questions/60276121/textinput-cursor-jump-to-right-end-when-the-input-is-empty
https://github.com/facebook/react-native/issues/28733
still actual
This issue is still a thing. In my case, first focus of the empty TextInput behaves correctly. The issue triggers when the user empties the text input. Placeholder then appears and cursor jumps to the right.
@fabriziobertoglio1987 thanks for taking a look at this!
Adding/Removing the placeholder triggers the problem. Tested on latest master
possible solution inside
ReactTextInputManager
. Need to do extensive testing.the problems seems to be connected to the use of the
Stringish
type for theplaceholder
field, which allows placeholder to default tonull
instead ofempty string
.https://github.com/facebook/react-native/blob/5cde6c5e7d440e62d21ef858d77ed185df8a2da0/Libraries/Components/TextInput/TextInput.js#L605
https://github.com/facebook/react-native/blob/5cde6c5e7d440e62d21ef858d77ed185df8a2da0/flow/Stringish.js#L14
Probably value of
null
causes problems when placeholder value is removed andmeasure
is triggered to re-compute thecontent
size…The issue is caused by the useage of Maybe Types like
?
which allow to passnull
as value.Seems like the one above is the easiest solution to implement as there are other logic built on top of this
placeholder
prop that could use the value ofnull
… additionally change in the type would break old applications … which may passplaceholder={null}
I found a possible solution, the issue is caused from calling the
placeholder
setter before calling thetextAlign
setter.Adding to the below method
https://github.com/facebook/react-native/blob/c8fed9e3858876c4e9cfe452a9f51c9241f82aad/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java#L848-L855
Does not cause the bug.
While if we set the text via the javascript setter prop
placeholder
https://github.com/facebook/react-native/blob/c8fed9e3858876c4e9cfe452a9f51c9241f82aad/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java#L407-L410
setHint
is called before mysetGravity(Gravity.CENTER_HORIZONTAL)
and it breaksI already experienced this with other issues in react-native, so I believe that I can publish a pull request to fix this within end of this week.
Thanks a lot 😃