Incosistent behavior on setting selection using TextInput setNativeProps

This issue has been tracked since 2022-09-15.

Description

I want to move the cursor to the end of the input when it gets focus, so I use setNativeProps:

<TextInput
  value={text}
  onChangeText={setText}
  onFocus={() => {
    textInputRef.current?.setNativeProps({
      selection: {
        start: text.length,
        end: text.length,
      },
    });
  }}
/>

However, the input behaves differently on Android and iOS. On iOS, the cursor jumps to the end as expected and inputting text works. On Android, though the cursor jumps to the end, it "locks" to that position on inputting text (see the video attached below).

I try to use -1 instead of text.length. In this case, the Android works but on iOS the cursor jumps to the start instead of the end.

It looks like a Android specific bug.

Version

0.70.0

Output of npx react-native info

info Fetching system and libraries information...
System:
    OS: macOS 12.6
    CPU: (8) x64 Apple M2
    Memory: 21.76 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 14.20.0 - ~/.nvm/versions/node/v14.20.0/bin/node
    Yarn: 1.22.15 - ~/.nvm/versions/node/v14.20.0/bin/yarn
    npm: 6.14.17 - ~/.nvm/versions/node/v14.20.0/bin/npm
    Watchman: 2022.09.12.00 - /opt/homebrew/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.4, iOS 16.0, macOS 12.3, tvOS 16.0, watchOS 9.0
    Android SDK: Not Found
  IDEs:
    Android Studio: Chipmunk 2021.2.1 Patch 2 Chipmunk 2021.2.1 Patch 2
    Xcode: 14.0/14A309 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.16.1 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.1.0 => 18.1.0
    react-native: 0.70.0 => 0.70.0
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

  1. Create a new project
  2. Write the following components in App.js(basically, removed the demo code and add my input-related code):
const CursorDemo = () => {
  const [text, setText] = useState('long hello world');
  const amountInput = useRef<TextInput>(null);
  return (
    <View>
      <TextInput
        ref={amountInput}
        value={text}
        onChangeText={setText}
        onFocus={() => {
          amountInput.current?.setNativeProps({
            selection: {
              start: text.length,
              end: text.length,
            },
          });
        }}
      />
    </View>
  );
};

const App: () => Node = () => {
  const isDarkMode = useColorScheme() === 'dark';

  const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
  };

  return (
    <SafeAreaView style={backgroundStyle}>
      <StatusBar
        barStyle={isDarkMode ? 'light-content' : 'dark-content'}
        backgroundColor={backgroundStyle.backgroundColor}
      />
      <CursorDemo />
    </SafeAreaView>
  );
};

export default App;
  1. Run app on iOS and Android respectively, and tap the middle area of the input to focus on it, and expect the cursor to jump to the end of the input.

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

The full project demostrating this issue in here: https://github.com/perqin/NativePropsSelectionIssue.

The video on Android:

1_1663226606.mp4
More Details About Repo
Owner Name facebook
Repo Name react-native
Full Name facebook/react-native
Language JavaScript
Created Date 2015-01-09
Updated Date 2022-10-05
Star Count 105161
Watcher Count 3671
Fork Count 22480
Issue Count 2227

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date