Skip to content

On Android, TextInput does not allow for selecting, copying, or pasting text in a lot of circumstances. #28366

@Rob117

Description

@Rob117

Description:

On Android, if you want to copy, select, paste, cut, etc. text with a long press inside of a text input, there is a well-known bug where when a component renders the TextInput will have editable set to some strange value. If you have a timeout adjusted and set it to tell editable to be true, as linked HERE, then it will work the first time the component is rendered. However, if you are on a stack navigator and go back a screen to render the component again, that suggested code stops working.

React Native version:

OS: macOS Mojave 10.14.6
CPU: (4) x64 Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
Memory: 136.27 MB / 16.00 GB
Shell: 3.2.57 - /bin/bash

Binaries:
Node: 8.16.0 - ~/.nvm/versions/node/v8.16.0/bin/node
Yarn: 1.19.2 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v8.16.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
Android SDK:
API Levels: 23, 25, 26, 28
Build Tools: 23.0.1, 25.0.2, 26.0.1, 28.0.3
System Images: android-28 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom_64
IDEs:
Android Studio: 3.4 AI-183.6156.11.34.5692245
Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
npmPackages:
react: 16.9.0 => 16.9.0
react-native: 0.61.4 => 0.61.4
npmGlobalPackages:
react-native-cli: 2.0.1

Steps To Reproduce

I think there are a lot of open issues on this, but I'm more interesting in just having an SEO friendly documented work around because the existing not-solved issues appear to have been closed by the facebook resolver bot.

Expected Results

I expect copying and pasting text in Android to be a really painless process like it is on iOS. Unfortunately, that is not the case.

Workaround:

import React from 'react';
import { TextInput } from 'react-native';

// https://github.com/facebook/react-native/issues/20887
// I had to modify the code because pressing back on the stack would mess up the state.
// EVERY TIME THE COMPONENT IS FOCUSED ON ANDROID we need to set editable after a slight delay.
export default class InputField extends React.Component {
  state = {
    editable: false,
  };

  componentDidMount() {
    this.props.navigation.addListener('focus', () => {
      this.setState({ editable: false });
      setTimeout(() => {
        this.setState({ editable: true });
      }, 100);
    });
    this.props.navigation.addListener('blur', () => {
      this.setState({ editable: false });
    });
  }

  render() {
    return <TextInput {...this.props} editable={this.state.editable} />;
  }
}

Usage: Simply import the above in place of text input and make sure to pass navigation={this.props.navigation} as a prop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Component: TextInputRelated to the TextInput component.StaleThere has been a lack of activity on this issue and it may be closed soon.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions