Description
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.