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

Programmatic focus of TextInput in useEffect fails silently in Bridgeless mode on iOS #47359

Open
QichenZhu opened this issue Nov 2, 2024 · 3 comments
Labels
Component: TextInput Related to the TextInput component. Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. Platform: iOS iOS applications. Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)

Comments

@QichenZhu
Copy link
Contributor

QichenZhu commented Nov 2, 2024

Description

The focus() method of TextInput in useEffect doesn't work in Bridgeless mode on iOS. The input is not focused, and the soft keyboard doesn’t appear.

Even worse, the isFocused() method returns true regardless, so future calls to focus() are ignored because it considers the input already focused.

Steps to reproduce

  1. Build and run the iOS app with New Arch enabled.
cd ReproducerApp
yarn
bundle install
cd ios
RCT_NEW_ARCH_ENABLED=1 pod install
cd ..
yarn ios
  1. Check if the TextInput is focused initially. If so, the test passes. If not, proceed to steps 3-5.

  2. Click the Focus button.

  3. Click the Blur button.

  4. Click the Focus button.

Expected result: The TextInput is focused initially.

Actual result: The TextInput is not focused initially and after the first time clicking the Focus button. It is only focused after clicking Blur and then clicking Focus again.

React Native Version

0.76.1

Affected Platforms

Runtime - iOS

Output of npx react-native info

System:
  OS: macOS 14.5
  CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
  Memory: 9.90 GB / 24.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.18.0
    path: ~/.nvm/versions/node/v20.18.0/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.nvm/versions/node/v20.18.0/bin/yarn
  npm:
    version: 10.8.2
    path: ~/.nvm/versions/node/v20.18.0/bin/npm
  Watchman:
    version: 2024.07.29.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/penguin/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.4
      - iOS 17.4
      - macOS 14.4
      - tvOS 17.4
      - visionOS 1.1
      - watchOS 10.4
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
  Xcode:
    version: 15.3/15E204a
    path: /usr/bin/xcodebuild
Languages:
  Java: Not Found
  Ruby:
    version: 3.1.2
    path: /Users/penguin/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.0
    wanted: 15.0.0
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.76.1
    wanted: 0.76.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

N/A

Reproducer

https://github.com/QichenZhu/reproducer-react-native-textinput-focus

Screenshots and Videos

Bridgeless Enabled Bridgeless Disabled
bridgeless-enabled.mp4
bridgeless-disabled.mp4
@react-native-bot react-native-bot added Component: TextInput Related to the TextInput component. Platform: iOS iOS applications. labels Nov 2, 2024
@shubhamguptadream11 shubhamguptadream11 added Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules) and removed Needs: Triage 🔍 labels Nov 4, 2024
@shubhamguptadream11
Copy link
Collaborator

@QichenZhu
This is specific to New arch only.
I initially tried to delay the calling of .focus() and it somehow worked this way.

setTimeout(() => {
      textInputRef.current?.focus();
    }, 0);

This is weird. I am still finding out what's the exact issue

@s77rt
Copy link
Contributor

s77rt commented Nov 11, 2024

Problem

The useEffect is called too early before the mount instructions are executed i.e. before the components are registered in the view registry, due to the mount being async. The focus fails as there is no component view with the given reactTag.

Offending commits and PRs:

cc @sammy-SC @rubennorte

Temporarily solution

Patch packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp

@@ -483,7 +483,7 @@ jsi::Value UIManagerBinding::get(
           uiManager->completeSurface(
               surfaceId,
               shadowNodeList,
-              {.enableStateReconciliation = true, .mountSynchronously = false});
+              {.enableStateReconciliation = true, .mountSynchronously = true});
 
           return jsi::Value::undefined();
         });

Or set the RN flag disableEventLoopOnBridgeless=true but as far as I can the flag system is meant for internal use only.

@rubennorte
Copy link
Contributor

Thanks for reporting this. This is a known issue we're investigating in #47576.

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. Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. Platform: iOS iOS applications. Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)
Projects
None yet
Development

No branches or pull requests

5 participants