question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't modify text in TextInput onChangeText callback on Android

See original GitHub issue

🐛 Bug Report

On Android, modifying the text within the onChange (or onChangeText) callback causes corruption of the text in the TextInput. (Not tested on iOS.)

For example, I’m trying to force all caps in my TextInput field. (This is to work around the react native autoCapitalize issue described here: https://github.com/facebook/react-native/issues/8932). So if a lowercase letter is entered, I change it to uppercase in the callback. Unfortunately, alternate keystrokes cause the entire previous text to be duplicated, but only if the entered keystroke was lowercase.

So, when forcing all caps, entering 1234 results in 1234 showing up; entering ABCD results in ABCD showing up; but entering abcd results in AABCAABCD.

This issue disappears if assigning a Math.random() key to the TextInput; but then of course so does the keyboard focus, making this an unacceptable workaround.

To Reproduce

See “Bug Report” and “Code Example” sections.

Expected Behavior

One should be able to modify the value inside TextInput’s change callbacks, without the text becoming corrupted on the subsequent redisplay.

Code Example

export default class TestScr extends Component
{
  constructor(props)
  {
	super(props);
	this.state = { s6: '' };
  }
  textchg(event)
  {
	const {eventCount, target, text} = event.nativeEvent;
            // one would expect the contents of s6 to display after the redraw
	this.setState({ s6: text.toUpperCase() }); 
  }
  render()
  {
            // [same behavior if using onChangeText instead of onChange]
	let jsx0 = <View style={{ flexDirection: 'row' }} key={ 'hi' }>
		<TextInput placeholder={ 'hello' } value={ this.state.s6 }
			onChange={ (evt) => this.textchg(evt) }
			keyboardType={ 'default' } />
		</View>;
		
	return (<View style={{ backgroundColor: '#ffffff', padding: 10, }}>
		<ScrollView style={{ backgroundColor: '#ffffff', }}>
			{ jsx0 }
		</ScrollView>
	</View>);
  }
}

Environment

React Native Environment Info: System: OS: Linux 3.19 Ubuntu 14.04.3 LTS, Trusty Tahr CPU: (4) x64 Intel® Core™ i7-5500U CPU @ 2.40GHz Memory: 626.14 MB / 15.38 GB Shell: 6.18.01 - /bin/tcsh Binaries: Node: 8.11.3 - /usr/bin/node npm: 5.6.0 - /usr/bin/npm SDKs: Android SDK: API Levels: 10, 16, 23, 26, 27, 28 Build Tools: 19.1.0, 20.0.0, 21.1.2, 22.0.1, 23.0.1, 23.0.2, 26.0.3, 27.0.3, 28.0.2, 28.0.3 System Images: android-16 | ARM EABI v7a, android-23 | Intel x86 Atom_64, android-23 | Google APIs Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom npmPackages: react: 16.6.3 => 16.6.3 react-native: 0.58.6 => 0.58.6 npmGlobalPackages: create-react-native-app: 1.0.0 react-native-cli: 2.0.1

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:16
  • Comments:53 (6 by maintainers)

github_iconTop GitHub Comments

21reactions
fabriziobertoglio1987commented, Feb 9, 2021

Hello ReactNative Developers! 😃

I just prepared Pull Request https://github.com/facebook/react-native/pull/29070 that seems to solve this issue

PREVIEWS OF THE BUGFIX

BEFORE AFTER

You can contact me by email at fabrizio.developer@gmail.com

Please head over to the Pull Request https://github.com/facebook/react-native/pull/29070 and thumbs up if you like it. If you want to get this fix you can follow the instructions for building ReactAndroid or checkout my video introduction on forking react-native (patch-package does not work).

If you don’t like the pr please feel free to leave a code review or comment, I’ll be happy to add improvements and changes.

Thanks a lot 🙏 ☮️ 🏖️

21reactions
lgenzeliscommented, Dec 26, 2019

I am not sure if this would also work on IOS, but it solved the problem for me on Android. The answer is quite simple: NEVER use value when rendering a TextInput. Use defaultValue instead.

If this turns out to really fix the issue for every platform, maybe we could just issue a warning every time someone uses value as a prop to TextInput.

UPDATE: I’ve tried this in iOS, and it also works.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Can't modify text in TextInput onChangeText callback on Android
Umair, your issue seems different. In my case, the callbacks are being called just fine, but things get screwy when I modify the...
Read more >
TextInput - React Native
onChangeText ​. Callback that is called when the text input's text changes. Changed text is passed as a single string argument to the...
Read more >
Using input masks in React Native - LogRocket Blog
The react-native-text-input-mask library provides input masking features on both Android and iOS platforms. In this tutorial, we will cover:.
Read more >
Handle changes to a text field - Flutter documentation
1. Supply an onChanged() callback to a TextField or a TextFormField · 2. Use a TextEditingController. Create a TextEditingController; Connect the ...
Read more >
TextInput - ReactXP
Any attempt to modify the value will result in onChangeText , which allows the owning component to re-render with an updated value ....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found