Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextInput issues on Android after updating to version 0.63.0 #30503

Closed
mhv1 opened this issue Nov 30, 2020 · 28 comments · Fixed by fabOnReact/react-native-improved#16
Closed
Labels
Component: TextInput Related to the TextInput component. Needs: Triage 🔍 Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@mhv1
Copy link

mhv1 commented Nov 30, 2020

Description

After upgrading from React Native version 0.62.2 to 0.63.0 users of my app started observing duplicate words when typing on a TextInput. This happens when using Samsung keyboard with predictive typing or auto-correct enabled, making text fields practically unusable. Google keyboard seems to at least let them type normally, although some glitches are visible there too. This bug didn't happen on React Native 0.62.x and it's particularly bad for my app whose main functionality is form filling. I have tested with the latest release and the issue still exists.

20201130_113650

After browsing possible ways to fix this I resorted to setting the TextInput's keyboardType prop to visible-password on Android, thus disabling the auto-correct and typing suggestion functionality of the Samsung keyboard. However this is just a workaround for now.

Due to the nature of my app (form filling) some memoization and re-rendering optimizations have to be done. I have provided the most minimal example of how this works on the sample repository linked below. The rationale is listed on the "Steps To Reproduce" section.

React Native version:

System:
    OS: macOS 10.15.7
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 13.24 GB / 32.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.19.0 - ~/.nvm/versions/node/v12.19.0/bin/node
    Yarn: Not Found
    npm: 6.14.8 - ~/.nvm/versions/node/v12.19.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.8.4 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.7, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 23, 25, 26, 27, 28, 29
      Build Tools: 23.0.1, 25.0.2, 25.0.3, 26.0.2, 26.0.3, 27.0.3, 28.0.3, 29.0.2
      System Images: android-27 | Google Play Intel x86 Atom, 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.7/11E801a - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_232 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: 0.63.3 => 0.63.3 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Render multiple TextInput components on a FlatList and place it on a separate component. This will be the "Form" component and the TextInputs will be the form modules.
  2. Update the form modules' values from a Redux store. Every value is assigned to the corresponding TextInput based on a unique ID and it's queried from the store using a selector.
  3. The piece of the Redux store containing the form module values is also passed to the "Form" component to be used for other operations.
  4. Override the "shouldComponentUpdate" method on the "Form" component to avoid it being re-rendered completely every time a form module value is updated. We only want the form module being updated to be rendered.
  5. Type on any of the form modules. If using a Samsung keyboard many of the characters typed will be duplicated. Try moving the cursor to the middle of the sentence typed and try deleting some characters ans you will notice the cursor jumping back and deleting more than one character at a time. This last issue is also seen when using Google keyboard.

Expected Results

  • TextInputs should behave correctly regarding on the keyboard being used.
  • Values for these components should be able to be updated from a Redux store in any way necessary and overriding "shouldComponentUpdate" methods on the parent component shouldn't affect the way the text is displayed while typing.

Like I mentioned before, everything was working fine with my app prior to version 0.63.0. I noticed on the release notes some changes where made to the TextInputState but I don't see how these changes apply to my case. I need to access different sections of my Redux store, including the form module values, in many of my components.

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

You can see my case and how the bug is reproduced on this repository: https://github.com/MHV1/rn-text-input-issue

Thank you for your help in advance :)

@react-native-bot react-native-bot added Component: TextInput Related to the TextInput component. Platform: Android Android applications. labels Nov 30, 2020
@vittau
Copy link

vittau commented Dec 3, 2020

Same here. We have just upgraded from Expo 37 to 39, and with it this major problem appeared.
Since the only publishable version (Google Play) at the moment is RN 63, this bug is literally crippling our ability to push new builds.

@antonello-alfatauristudio

any news?

@wengkhing
Copy link

wengkhing commented Dec 14, 2020

We are experiencing the same issue after upgrading to RN 0.63.3
However, this issue only happened to multiline input and does not affect single line input.

Dec-14-2020 16-51-32

@jyungtong
Copy link

jyungtong commented Dec 17, 2020

We are experiencing this issue. However, slightly different is that we are using redux-form with the TextInput component. We are able to solved it by populating the form state to props. In our cases here, we do this:

import { connect } from 'react-redux';

@connect(
  state => ({ ...state.form })
)
export default YourComponent;

This seems solved the issue. The first thing you probably could try out is populate the whole ...state to see if it works. Then narrow down to find out which props you are going to need it.

Hopefully this does help.

@ab-sami
Copy link

ab-sami commented Dec 28, 2020

Facing the same issue after upgrading to RN 0.63.4.
Tried @jyungtong solution/suggestion but don't see much difference in our case.

@vittau
Copy link

vittau commented Jan 26, 2021

We went through all of our apps and changed every form to Formik, mostly due to this issue. The lack of attention given to this issue is concerning.

@andordavoti
Copy link

andordavoti commented Feb 19, 2021

Also facing the same issue on 0.63.4. Had to downgrade to 0.62.2 to fix the issue in the meantime.

@thaiphamvan
Copy link

Description

After upgrading from React Native version 0.62.2 to 0.63.0 users of my app started observing duplicate words when typing on a TextInput. This happens when using Samsung keyboard with predictive typing or auto-correct enabled, making text fields practically unusable. Google keyboard seems to at least let them type normally, although some glitches are visible there too. This bug didn't happen on React Native 0.62.x and it's particularly bad for my app whose main functionality is form filling. I have tested with the latest release and the issue still exists.

20201130_113650

After browsing possible ways to fix this I resorted to setting the TextInput's keyboardType prop to visible-password on Android, thus disabling the auto-correct and typing suggestion functionality of the Samsung keyboard. However this is just a workaround for now.

Due to the nature of my app (form filling) some memoization and re-rendering optimizations have to be done. I have provided the most minimal example of how this works on the sample repository linked below. The rationale is listed on the "Steps To Reproduce" section.

React Native version:

System:
    OS: macOS 10.15.7
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 13.24 GB / 32.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.19.0 - ~/.nvm/versions/node/v12.19.0/bin/node
    Yarn: Not Found
    npm: 6.14.8 - ~/.nvm/versions/node/v12.19.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.8.4 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.7, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 23, 25, 26, 27, 28, 29
      Build Tools: 23.0.1, 25.0.2, 25.0.3, 26.0.2, 26.0.3, 27.0.3, 28.0.3, 29.0.2
      System Images: android-27 | Google Play Intel x86 Atom, 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.7/11E801a - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_232 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: 0.63.3 => 0.63.3 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Render multiple TextInput components on a FlatList and place it on a separate component. This will be the "Form" component and the TextInputs will be the form modules.
  2. Update the form modules' values from a Redux store. Every value is assigned to the corresponding TextInput based on a unique ID and it's queried from the store using a selector.
  3. The piece of the Redux store containing the form module values is also passed to the "Form" component to be used for other operations.
  4. Override the "shouldComponentUpdate" method on the "Form" component to avoid it being re-rendered completely every time a form module value is updated. We only want the form module being updated to be rendered.
  5. Type on any of the form modules. If using a Samsung keyboard many of the characters typed will be duplicated. Try moving the cursor to the middle of the sentence typed and try deleting some characters ans you will notice the cursor jumping back and deleting more than one character at a time. This last issue is also seen when using Google keyboard.

Expected Results

  • TextInputs should behave correctly regarding on the keyboard being used.
  • Values for these components should be able to be updated from a Redux store in any way necessary and overriding "shouldComponentUpdate" methods on the parent component shouldn't affect the way the text is displayed while typing.

Like I mentioned before, everything was working fine with my app prior to version 0.63.0. I noticed on the release notes some changes where made to the TextInputState but I don't see how these changes apply to my case. I need to access different sections of my Redux store, including the form module values, in many of my components.

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

You can see my case and how the bug is reproduced on this repository: https://github.com/MHV1/rn-text-input-issue

Thank you for your help in advance :)

I removed the props value and add defaultValue in TextInput. It's work for me

@fabOnReact
Copy link
Contributor

Please, is it possible to merge this PR in the next version ?

To answer the question of when the pr #29070 which fixes this issue will be released in the next version of React Native, I suggest you to follow the discussions at https://github.com/react-native-community/releases/issues by subscribing to those threads. The process of releasing a new version with a bug fix is the following:

@andordavoti
Copy link

React Native v0.64.1 is out and there is still no fix. This is very concerning...

@sannajammeh
Copy link

Dark mode 6months ETA. And this since Nov 30th.
Refactoring to Flutter.

@Svarto
Copy link

Svarto commented Jul 1, 2021

Had this issue as well but using Recoil. Seems like it's related to Global State, I just refactored to the value and onTextChange all being linked to useState in the same component (i.e. local state only) and then utilizing a useEffect to update and keep Global State synced with the local state of the Textinput. This fixed all problems for me.

@andordavoti
Copy link

In my case, it was an issue with React Native Paper. More info here: GitHub Issue

@cdunkel
Copy link

cdunkel commented Aug 3, 2021

I'm seeing a similar TextInput issue, but it's not quite the same and I'm curious if it's related or if anyone knows of what might be happening.
AndroidTyping
Here, whenever I place the cursor in the middle of existing text and try to type it moves my cursor one character to the left after each keystroke.

This just started happening after I upgraded to React Native 0.64.2. It does not happen on iOS.

@cdunkel
Copy link

cdunkel commented Aug 8, 2021

An update on what I've found for anyone who might be looking into this.

I've found that in TextInput.js, onSelectionChange is getting called twice, once with the new (correct) selection value and then again with the old (incorrect) selection value.

const _onSelectionChange = (event: SelectionChangeEvent) => {
    props.onSelectionChange && props.onSelectionChange(event);

    if (inputRef.current == null) {
      // calling `props.onSelectionChange`
      // may clean up the input itself. Exits here.
      return;
    }

    setLastNativeSelection({
      selection: event.nativeEvent.selection,
      mostRecentEventCount,
    });
  };

If I set a breakpoint and check event.nativeEvent.selection the callback gets called twice. First with selection = { end: 6, start: 6 } and then immediately afterwards with selection = { end: 5, start: 5 }.

I haven't been able to figure out exactly where the duplication is happening. If I get more time to look into it I'll post an update here.

@fabOnReact
Copy link
Contributor

This issue is solved with my pr

@cdunkel
Copy link

cdunkel commented Aug 8, 2021

@fabriziobertoglio1987, thanks! I completely missed your previous comment which said this 🤦 .

Do you know if this might make it into 0.65.0, whenever that finally gets released?

SiobhyB pushed a commit to WordPress/gutenberg that referenced this issue Aug 10, 2021
The purpose of this commit is to address the text entry issues that currently exist for the TextInput component, as described here: facebook/react-native#30503

A working workaround propose in that thread is to replace the "value" prop with "defaultValue".
@cristianoccazinsp
Copy link
Contributor

Still an issue with RN 0.65, wow!. Any work arounds?

SiobhyB added a commit to WordPress/gutenberg that referenced this issue Sep 3, 2021
)

* Resolve render error

This commit aims to fix the render error outlined here: #33057 (review)

The "outside" changes that happen when text is changed in the BottomSheetTextControl component should not be called directly from that component. Instead, they're now called within the useEffect hook.

* Replace "value" prop with "defaultValue"

The purpose of this commit is to address the text entry issues that currently exist for the TextInput component, as described here: facebook/react-native#30503

A working workaround propose in that thread is to replace the "value" prop with "defaultValue".

* Simplify component by removing unecessary hooks

The introduction of the "defaultValue" prop in f6d9697 means that it's no longer necessary to keep the value in state. "defaultValue" allows for text to be automatically changed as it's typed. See: https://reactnative.dev/docs/textinput#defaultvalue

We don't need to use "onChangeText" for the purpose of updating the input's text and can instead use it to invoke the "onChange" function.

We can also remove the useState and useEffect hooks, as they're not necessary to update the component's value.
@mawlicious
Copy link

this issue seems to still be up, has any workarounds been found?

@hntddt123
Copy link

Try using defaultValue and supply a prop or a state like defaultValue={this.props.text} instead of value if you need the auto complete on keyboard

@CaptainHaider
Copy link

still

@abduliOS
Copy link

Any solutions for RN0.64.1?
it is only happening on android

@filipepratalima
Copy link

Still happening on RN0.64.3, only on Android

@MehmetKaplan
Copy link

When TextBox is to be used as a controlled component, it fails in Android and iOS as well. iOS failure rate is smaller because of - I guess - the powerful hardware, but if written very quickly the cursor loses the correct spot.

@hntddt123 's suggestion is very good but does not apply for the controlled components.

Atomic example:

import * as React from 'react';
import {  View, Text, TextInput } from 'react-native';

export default function App() {
   const [textInputEmail, setTextInputEmail] = React.useState('');
   return (
      <View style={{height: '100%', width: '100%', alignItems: 'center', justifyContent: 'center', }} >
         <TextInput
            label="Email"
            value={textInputEmail}
            onChangeText={email => setTextInputEmail(email.toLowerCase())}
            style={{borderWidth: 4, width: '62%'}}
         />
     </View>
  );
}

I am afraid there may be a fundamental architectural problem here. Any fix / suggestion is appreciated.

@github-actions
Copy link

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Sep 25, 2023
@github-actions
Copy link

github-actions bot commented Oct 2, 2023

This issue was closed because it has been stalled for 7 days with no activity.

@github-actions github-actions bot closed this as completed Oct 2, 2023
@fabOnReact
Copy link
Contributor

Do you still experience this issue?

I have four years of experience maintaining facebook/react-native and I specialize in the Text and TextInput components. I currently have 58 facebook/react-native PRs.

If you still experience this issue, I will prepare a patched release with the fix.

Thanks a lot

@fabOnReact
Copy link
Contributor

This PR is included in the react-native-improved library:

react-native-improved

  • Supports ONLY react-native 0.73.
  • Supports only old architechture (new architechture is WIP)

Set-up

In package.json

 "scripts": {
+  "postinstall": "yarn run react-native-patch"
 }

Then

npm

npm install react-native-improved --save-dev

yarn v1

yarn add react-native-improved --dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: TextInput Related to the TextInput component. Needs: Triage 🔍 Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet