facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.2k stars 24.33k forks source link

TextInput value can't be changed during onChangeText[Android] #26017

Closed 509dave16 closed 5 years ago

509dave16 commented 5 years ago

Summary

When attempting to ignore certain characters by controlling the state value that's passed to the TextInput, the TextInput's natively held value get's out of sync. This makes it impossible to enforce a particular text pattern at the time of a user entering the text. This exact issue was occurring before React Native 57.1 on iOS, as noted here in this now closed issue #18874 . There is also this existing issue #23578 that covers this bug that still exists on Android. If you would like I can move parts of my issues content over there as comments.

React Native version: 0.59.8(based on Expo SDK 34)

Steps To Reproduce

  1. Implement an onChangeText event handler that will selectively choose to not update the state value(which control's the TextInput's natively stored value). For example, let's say uppercase letters like 'A', 'B', 'C', etc...
  2. Enter characters other than the ones to be ignored
  3. Enter at least 1 or more of the ignored characters
  4. Go back to entering characters other than the ones to be ignored

Describe what you expected to happen:

  1. Enter 'abc', resulting in 'a', 'ab', and 'abc' being passed to onChangeText handler each of which are valid and are set on the state value that controls the TextInput.
  2. Enter 'A' which should be ignored, thus 'abcA' will not be set on the state value that controls the TextInput. Meaning only 'abc' is still displayed in the TextInput.
  3. Enter 'd', which should result in onChangeText handler receiving 'abcd' which is valid and will be set on the state value that controls the TextInput.

Snack, code example, screenshot, or link to a repository

  1. Snack here
  2. Screenshots that follow the steps outlined in the Describe what you expected to happen section above. Notice after entering 'A' that a pattern emerges in the natively held text value. It concatenates the characters that have been entered to the state controlled value that has remained at 'abc' since the character 'A' was entered.
    • Enter 'a'
    • Enter 'b'
    • Enter 'c'
    • Enter 'A'
    • Enter 'b'
509dave16 commented 5 years ago

These are the best solutions that I could come up with. A text input mask that displays the transformed text. And an algorithm that takes the correct value from the out of sync native value provided by the TextInput: https://snack.expo.io/@509dave16/android-text-input-out-of-sync-solutions

509dave16 commented 5 years ago

@brentvatne Should I move all this information to issue #23578? Mine is kind of a duplicate. I was only able to find the other issue after writing up this very exhaustive issue. So I figure if asked, I could migrate all of this information to the other issue.

brentvatne commented 5 years ago

@509dave16 - yeah, that could be useful to add your report as a comment on the existing issue and close this one

509dave16 commented 5 years ago

@brentvatne Awesome. Thank you for your reply! Closing issue. This report has been added here to this already existing issue: https://github.com/facebook/react-native/issues/23578#issuecomment-521821027

rashidmakki commented 3 years ago

@509dave16 This problem was happening with my react-native App too. What I did is that I created an individual components out side the main component( where we will place this component) keeping TextInput as a whole(i.e according to our requirement that means what field do we need) in one single component. Passing the value as props to this component and changing it whenever we require using onChangeText. The idea is that we need to change only this particular component not the whole screen. The problem was solved in my App.