React-native: [iOS] TextInput .focus() does not work when editable is false initially

Created on 7 Apr 2018  路  5Comments  路  Source: facebook/react-native

Environment

Environment:
OS: macOS Sierra 10.12.6
Node: 9.10.1
Yarn: 1.5.1
npm: 5.6.0
Watchman: 4.7.0
Xcode: Xcode 9.2 Build version 9C40b
Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: 0.55.1 => 0.55.1

Steps to Reproduce


https://snack.expo.io/@riwu/textinput-focus

import React, { Component } from 'react';
import { Button, View, TextInput, Text } from 'react-native';

export default class App extends Component {
  state = {
    editable: false,
  };
  render() {
    return (
      <View style={{marginTop: 100}}>
        <Button
          title="Focus"
          onPress={() => {
            this.setState({ editable: true });
            this.ref.focus();
          }}
        />
        <TextInput
          ref={ref => {
            this.ref = ref;
          }}
          opacity={this.state.editable ? 1 : 0}
          editable={this.state.editable}
        />
        <Text>Position below text input</Text>
      </View>
    );
  }
}

Expected Behavior

On clicking "Focus", the input should be focused (on Android this works).

Actual Behavior

On iOS, input did not get focused.

TextInput iOS Ran Commands For Stack Overflow Locked

Most helpful comment

setState is asynchronous, move your focus call into a callback and you'll get your intended behavior.

this.setState({ editable: true }, ()=>{
    this.ref.focus();
});

All 5 comments

setState is asynchronous, move your focus call into a callback and you'll get your intended behavior.

this.setState({ editable: true }, ()=>{
    this.ref.focus();
});

@lfkwtz

  1. calling .focus() on uneditable TextInput works on Android, so the inconsistency should probably be fixed unless it's an OS limitation (this is unlikely as it used to work until ~v0.5x) rather than implementation difference.
  2. even if this is intended, pressing the "Focus" button second time should work since editable will be true by then.

Also in the actual app, the state that determines the editable prop is stored in Redux, so I'd have to execute the .focus() in componentDidUpdate or change my action from (...) => ({...}) to

(...) => dispatch => {
  dispatch({...});
  return Promise.resolve(); // not very elegant
}

This also delays the display of keyboard until the component re-renders, though that might be a better behaviour as the user will not be able to input text until then.

This issue looks like a question that would be best asked on Stack Overflow.

Stack Overflow is amazing for Q&A: it has a reputation system, voting, the ability to mark a question as answered. Because of the reputation system it is likely the community will see and answer your question there. This also helps us use the GitHub bug tracker for bugs only.

Will close this as this is really a question that should be asked on Stack Overflow.

Is it not clear that this is a bug report? There's no reason why pressing the "Focus" twice wouldn't trigger the keyboard input.

This is a bug. I cannot get onFocus to work if my TextInput has editable={false} property.

Was this page helpful?
0 / 5 - 0 ratings