34

I have a screen in my React Native application in which I have few text fields.

I was wondering if there is any way in which on screen load my keyword opens automatically and focuses on my first text input field?

I was searching for something like stateAlwaysVisible in android.

Harkirat Saluja
  • 7,768
  • 5
  • 47
  • 73

9 Answers9

51

The keyboard should open automatically when <TextInput /> is focused. You can use the autoFocus prop to make it focus when the element mounts (link)

Blue Bot
  • 2,278
  • 5
  • 23
  • 33
Ziarno
  • 7,366
  • 5
  • 34
  • 40
  • Looks like i missed this while going through the documentation :( .. let me try it once... – Harkirat Saluja Feb 25 '17 at 13:26
  • 33
    `autoFocus` does not seem to fire when the page loads through stack navigation. It ends up focusing the `textInput` but does not open the keyboard. – SoundStage Sep 20 '17 at 14:10
  • i need to show the user this page has textInput, so when i navigate to this page the textInput should focus and also keyboard should open automatically .. how to do that? @Ziarno –  Oct 13 '17 at 06:21
  • does `` not work for you? it should focus the field on mount, and the keyboard should show – Ziarno Oct 13 '17 at 09:42
  • 31
    Manual focus by refs doesn't trigger keyboard. There is a Keyboard.dismiss(), but I don't see a show() on React Native docs either. – Dan Jan 17 '18 at 17:35
  • 5
    @Dan same problem here. Trying to focus a TextInput by ref and open the Keyboard. Did you find any solution? – Dror Bar Jan 30 '19 at 16:09
  • 5
    This answer does not answers the question, it is a workaround for a specific case. If one doesn't wants/can use autofocus, then this answer won't work. The Keyboard is not shown on focus – Jaqueline Passos Feb 29 '20 at 15:52
  • 1
    can confirm that autoFocus works on android with stack navigation – user1462498 Apr 16 '21 at 13:08
  • 1
    anybody has made it work? autoFocus doesnt fix it for me. – an0o0nym Jun 18 '21 at 00:02
17

This trick worked for me

setTimeout(() => InputRef.current.focus(), 100)
hamzaahzam
  • 306
  • 3
  • 14
16

My way (there was a problem with focusing and showing a keyboard on component render)

import { InteractionManager, TextInput } from 'react-native';

...

inputRef = React.createRef();

componentDidMount() {
  this.focusInputWithKeyboard()
}

focusInputWithKeyboard() {
  InteractionManager.runAfterInteractions(() => {
    this.inputRef.current.focus()
  });
}

render() {
  <TextInput ref={this.inputRef} />
}
bobu
  • 908
  • 8
  • 14
10

another solution :)

import React, { useRef } from 'react'

export function mycomponent(props) {
   const inputRef = useRef();
   
   return(
         <TextInput 
           ref={inputRef}
           onLayout={()=> inputRef.current.focus()}>
         </TextInput>
   )
}

amirhosein
  • 844
  • 9
  • 24
  • 1
    This is the best answer that just work ! In case you're trying to focus an input inside a modal, use the Modal onShow event instead of the TextInput onLayout and it will work flowlessly. inputRef.current?.focus()}/> – malko Dec 08 '22 at 17:45
  • `onLayout` doesn't invoked when navigating back to that screen! – Cagri Uysal May 09 '23 at 10:09
1

It worked for me.

<TextInput
        autoFocus={false}
        autoCapitalize="none"
        onChangeText={(val) => {
            props.onChange(val);
        }}
        value={null}
        defaultValue={props.defaultValue}
        ref={(ref) => {

            if( ref !== undefined && ref && !ref.isFocused() ){

                ref.focus();
            }
        }}
        {...propsMerge}
    />
user2573099
  • 63
  • 1
  • 6
1

This is how it looks in code, using the setTimeout() Hook

import { StyleSheet, Text, View, TextInput } from "react-native";
import React from "react";

const HomeScreen = () => {
  const inputRef = React.useRef();

  setTimeout(() => inputRef.current.focus(), 100);
  return (
    <View style={{ paddingVertical: 20 }}>
      <Text>circle</Text>
      <TextInput ref={inputRef} />
    </View>
  );
};

export default HomeScreen;

const styles = StyleSheet.create({});
questerstudios
  • 111
  • 1
  • 6
0

This seems to be working in my simulator. Have not confirmed on a real device.

constructor(props) {
  super(props);
  this.buildNameTextInput = React.createRef();
}
<TouchableOpacity
  style={styles.mainButton}
  onPress={() => {
    this.buildNameTextInput = true
    this.props.setSaveBuildModal(true)
  }}
>
  <Text style={styles.mainButtonText}> Save Build </Text>
</TouchableOpacity>

<TextInput
  autoFocus={!!this.buildNameTextInput}
  ref={this.buildNameTextInput}
  placeholder="Type a Name"
  autoCapitalize="words"
  style={{...styles.heroBtnText, marginVertical: 50}}
  onChangeText={buildName => this.props.setCurrentBuildName(buildName)}
  value={this.props.buildName}
/>
  1. I needed the constructor to register the reference
  2. The handler sets a local variable to true
  3. autoFocus will trigger the field to be focused. The keyboard sometimes opens up on android simulator (this I cannot explain).
  4. ref is for the reference to the DOM element
Cyrois
  • 439
  • 4
  • 9
0

You can maintain a ref to the TextInput as textInputRef and use this.textInputRef.focus()

naheed.shamim
  • 340
  • 2
  • 11
-1

The selected solution did not work for me due to stack navigation (see comment of "SoundStage" on selected solution)

I added a new variable openTheKeyboard to the state initially set to false.

My hacky solution:

componentDidMount() {
  this.setState({ openTheKeyboard: true });
}

componentDidUpdate() {
  if (this.state.openTheKeyboard) {
    this.textInput.focus();
    this.setState({ openTheKeyboard: false });
  }
}
Mazel
  • 49
  • 4