0
votes

In react-navigation, what is the best way to handle a tab that has a form with an autoFocus input that automatically pulls up the keyboard?

When the Navigator initializes all the screens, it automatically displays the keyboard even though the screen without the autoFocus element is showing first.

I want it to open the keyboard when I'm on the tab with the form, but close it when I leave that view.

Here is an example (and an associated Gist):

App.js

const AppNavigator = TabNavigator( {
  listView: { screen: TheListView },
  formView: { screen: TheFormView }
} )

TheFormView.js

const TheFormView = () => {
  return (
    <View style={{ marginTop: 50 }}>
      <TextInput
        autoFocus={ true }
        keyboardType="default"
        placeholder="Blah"
      />
    </View>
  )
}

TheListView.js

const TheListView = () => {
  return (
    <View style={{ marginTop: 50 }}>
      <Text>ListView</Text>
    </View>
  )
}
2

2 Answers

0
votes

You should use lazy on TabNavigator config: https://github.com/react-community/react-navigation/blob/master/docs/api/navigators/TabNavigator.md#tabnavigatorconfig

This prevents the screen from being initialised before it's viewed.

Also consider having some kind of state management or look for Custom Navigators (https://reactnavigation.org/docs/navigators/custom) for setting the autoFocus prop as true only when TheFormView is navigated to.

0
votes

This answer was out of date for me as of April 2020, but this worked for me:

import { useFocusEffect, } from "@react-navigation/native"
import React, { useEffect, useState, } from "react"
...
const CreateProfileScreen = ({ navigation, }) => {
   const [safeToOpenKeyboard, setSafeToOpenKeyBoard] = useState(false)
   ...
   useFocusEffect(
        React.useCallback(() => {
            console.log("Navigated to CreateProfileScreen")
            setSafeToOpenKeyBoard(true)
            return () => {
                console.log("Navigated away from CreateProfileScreen")
                setSafeToOpenKeyBoard(false)
            }
        }, [])
    )
   ...
   return (<TextInput autoFocus={safeToOpenKeyboard}/>)
}