react-native: TextInput crashes an app if Samsung Keyboard uses Predictive Text & Suggest text corrections

Description

Main issue: Generated release .apk TextInput crash the app on Samsung when Predictive Text & Suggest text corrections is activated. React-native versions checked: 0.63.3, 0.67.2 Phones produced the issue: Samsung S20 Ultra, Samsung Galaxy S21 Plus Another possible issue: For all the crashes captured some parts of the text were underlined green or red, maybe the issue is with that suggestions… It was first produced by the production project based on 0.63.3v, then I created bare 0.67.2v project and added simple TextInput, and the issue still exists. Attaching a video so everybody can replicate.

Screenshot_20220216-094239_Samsung_Keyboard

https://user-images.githubusercontent.com/48454610/154644390-61bdd58c-e647-422d-b69b-c26dda88e721.mp4

Version

0.63.3, 0.67.2

Output of npx react-native info

System: OS: macOS 12.2.1 CPU: (8) arm64 Apple M1 Memory: 439.56 MB / 16.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 17.2.0 - /opt/homebrew/bin/node Yarn: 1.22.17 - /opt/homebrew/bin/yarn npm: 8.1.2 - /usr/local/bin/npm Watchman: 2021.12.13.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.2, iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3 Android SDK: API Levels: 29, 30, 32 Build Tools: 28.0.3, 29.0.2, 30.0.0, 30.0.2, 32.0.0 System Images: android-29 | Google APIs Intel x86 Atom, android-29 | Google Play ARM 64 v8a, android-31 | Google APIs ARM 64 v8a, android-32 | Google APIs ARM 64 v8a, android-32 | Google APIs Intel x86 Atom_64 Android NDK: Not Found IDEs: Android Studio: 2020.3 AI-203.7717.56.2031.7935034 Xcode: 13.2.1/13C100 - /usr/bin/xcodebuild Languages: Java: 1.8.0_292 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.67.2 => 0.67.2 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

  1. Get my repo: https://github.com/BohdanSol/projectTwo
  2. yarn install
  3. Generate keystore, put it inside android>app. Change values regarding keystore inside gradlew.properties
  4. From root cd android && ./gradlew assembleRelease
  5. Test generated apk in real device

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

https://github.com/BohdanSol/projectTwo

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 9
  • Comments: 63 (2 by maintainers)

Commits related to this issue

Most upvoted comments

We were able to reproduce this bug and we found that setting autoCorrect to false in the TextInput solves the issue. We are planning to roll out this soon and expect ANR numbers to go down. I’ll keep you posted.

Try this and let me know if it works for you.

P.S.: Since this is happening only for Samsung devices with Android 12 I made this util to only set autoCorrect to false when the device meets these props:

import { toLower } from 'lodash';
import { getSystemVersion, useManufacturer } from 'react-native-device-info';

export const useIsSamsungWithAndroid12 = (): boolean => {
  const { loading, result } = useManufacturer();
  const systemVersion = getSystemVersion();

  return !loading && toLower(result) === 'samsung' && systemVersion.startsWith('12');
};

Hey fellow devs, please upvote the comment under the Meta discussion about what to improve: https://github.com/react-native-community/discussions-and-proposals/discussions/528#discussioncomment-3890273

let’s hope it will get enough attention

Bad bot, issue still exists to this day

We’ve finally solved this issue for our app, the root cause was re-renders locking up the UI.

Echoing @Houguiram on this comment https://github.com/facebook/react-native/issues/33139#issuecomment-1335147934, making the component fully uncontrolled makes a huge difference.

For us we had a class component using Formik, so memoizing wasn’t possible. Formik was causing double re-renders every time the user typed. We refactored our component to remove Formik and make sure that zero re-renders happened while typing. This might be complex for some if you’re doing something like updating state on the component onDataChanged. We’re using mobx as our data store and are simply updating the value in data store with onDataChanged, to be accessed when the form is submitted. Since there’s no state update…no re-render.

Obviously it’d still be great to figure out the actual root cause of why this is only happening on Samsung devices. But for those looking for immediate relief, look into how often your components are re-rendering on text changes and try to eliminate/reduce that.

I’ve been experimenting on my S20 FE 5G on Android 12 and here is what I found:

  • The issue appears to be extreme slowness which leads to crashes/ANRs when typing on a TextInput with the Samsung keyboard with text suggestions on
  • The issue can be quickly and reliably reproduced by pasting a big chunk of text in the input then starting to type
  • The issue happens with controlled inputs i.e. when passing an externally controlled value prop
  • The issue happens with uncontrolled inputs with a default value, but not for uncontrolled inputs without a default value! Having an onChange doesn’t seem to make a difference in either cases.
  • That last point makes me think that there must be something that could be done at react-native’s TextInput level but I haven’t looked into how it’s implemented yet.
  • This also means that if your users need text suggestions and you don’t need a controlled input or a default value, you could try this workaround. If someone could confirm that it works for them too, it would be great to confirm it as a viable solution/workaround.

@Saad-Bashar We’ve rolled out the fix and have confirmation from several users that it resolved the issue for them.

For anyone dealing with this issue, the freezing only seems to be happening using the default Samsung keyboard. We’ve been able to recommend to our users to install Google’s Keyboard and the freezing does not happen.

https://play.google.com/store/apps/details?id=com.google.android.inputmethod.latin&hl=en_US&gl=US

Not a great long term solution, but hopefully can help provide some relief while this is investigated.

@LunyovYuriy yes right its not a perfect solution but its not crashing the app and autocorrect is not working when we use email-address keyboard.

I have the same issue and tried some of the solutions but not working fine. Now simply I have fixed this by changing the keyboard type to email-address.

Thanks this helps, but still not a perfect solution, because of adding “@” and “.com” buttons to the keyboard layout, but works better with multiline inputs than “visible-password” type

I have the same issue and tried some of the solutions but not working fine. Now simply I have fixed this by changing the keyboard type to email-address.

@sabidhasan You can use two forms

<Textinput value={this.state.text}/>

or

<Textinput>
<Text>{this.state.text}</Text>
</Textinput>

I doubt that there is a difference, but worth checking. I am not familiar with Textinput implementation.

Thanks for the response. Confirming that the latter form doesn’t make a difference - the keyboard/inputs still slow down after typing ~1 paragraph of text. Appreciate the help/suggeston though!

@sabidhasan You can use two forms

<Textinput value={this.state.text}/>

or

<Textinput>
<Text>{this.state.text}</Text>
</Textinput>

I doubt that there is a difference, but worth checking. I am not familiar with Textinput implementation.

@JuanAlejandro working as expected as workaround for this kind of issue. Thank you very much!