facebook / react-native

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

TextInput keyboard getting dismissed automatically #45798

Open 1880akshay opened 1 month ago

1880akshay commented 1 month ago

Description

When a TextInput is wrapped with a View, and the View is given conditional styles based on the focus state of the TextInput, the keyboard gets dismissed as soon as it is tapped to gain focus. So, as soon as onFocus is called, onBlur is triggered automatically. Note that this is not happening for all style keys, but I have encountered it only for "elevation" and "shadowColor" properties till now.

The issue is only happening when new architecture is enabled on both android and ios.

Steps to reproduce

Here is a minimum reproducible example for the issue: https://github.com/1880akshay/RN_NewArch_TextInput

React Native Version

0.74.3

Affected Platforms

Runtime - Android, Runtime - iOS

Areas

Fabric - The New Renderer

Output of npx react-native info

System:
  OS: macOS 13.6.7
  CPU: (10) arm64 Apple M1 Max
  Memory: 204.98 MB / 64.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.19.0
    path: ~/.nvm/versions/node/v18.19.0/bin/node
  Yarn:
    version: 1.22.21
    path: ~/.nvm/versions/node/v18.19.0/bin/yarn
  npm:
    version: 10.2.3
    path: ~/.nvm/versions/node/v18.19.0/bin/npm
  Watchman:
    version: 2024.07.15.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.2
      - iOS 17.2
      - macOS 14.2
      - tvOS 17.2
      - visionOS 1.0
      - watchOS 10.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2022.3 AI-223.8836.35.2231.10406996
  Xcode:
    version: 15.2/15C500b
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
    path: /usr/bin/javac
  Ruby:
    version: 3.3.0
    path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.3
    wanted: 0.74.3
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: Not found
  newArchEnabled: true

Stacktrace or Logs

-

Reproducer

https://github.com/1880akshay/RN_NewArch_TextInput

Screenshots and Videos

https://github.com/user-attachments/assets/7a70be20-4d74-4da1-9b07-aae8472f0a60

coado commented 1 month ago

Hey, I can check this out.

coado commented 1 month ago

The issue is that after clicking on TextInput one of the styles, that is added to the container, prevents flattening which causes adding remove and insert mutation on TextInput in differentiator. On the remove mutation, the TextInput loses focus, so the onBlur is triggered immediately after that. This will also happen on other styles, for instance setting opacity < 1, transform or any other style that would add FormsStackingContext trait on this view, which are defined here. It won't update areChildrenFlattened in differentiator to true, so the recursion will stop and the TextInput won't be added here to the list. It will cause differences in returned trees and it will generate above-mentioned mutations.

For the quick fix, you can add collapsable={false} to the View component:

<View collapsable={false} style={[styles.shadowBox, focus && styles.shadowBoxFocused]}>
  <TextInput
      placeholder="Text"
      style={{height: 60, width: 300, borderColor: 'black', borderWidth: 1}}
      onFocus={() => setFocus(true)}
      onBlur={() => setFocus(false)}
   />
</View>

The problem is that we cannot perform remove and insert mutations on something that needs to hold focus. I am not sure if searching for a solution that will work only for TextInput is a good idea. Is it good enough solution for now or should I proceed with something that will work in a broader scope?

1880akshay commented 1 month ago

@coado thanks for the prompt replies. I'll test this out (collapsable=false) and let you know if it works. Meanwhile, I am curious as to why this worked in old architecture and the issue is only happening with new architecture?

coado commented 1 month ago

The issue seems to be related to view flattening which was introduced in the new architecture. You can read more about it here

1880akshay commented 1 month ago

Thanks for the clarification @coado . Also, collapsable = false fix is working fine! I also wanted to know, that collapsable property exists on android even in old architecture and it did flatten the view hierarchies, I wonder how it used to work earlier.

coado commented 1 month ago

As far as I know, the previous flattening was way simplified and worked only on Android like you said. Unfortunately, I am not too educated how it worked on the old arch and docs are also not too comprehensive about that 😕