2

I have a react-native-paper TextInput that I want to focus automatically when I navigate to a screen (using react-native-navigation). I have tried setting autoFocus={true} on the TextInput, but that didn't work.

In another attempt, I tried to focus it manually by listening to the 'focus' event on the screen, but that only focused it the first time I opened the screen. Is there any way of getting it to work reliably?

export default function NewAccountScreen({ navigation }) {
  const [name, setName] = useState('');

  const textInputRef = createRef();

  // This isn't working, neither is autoFocus...
  const focusOnInput = () => {
    textInputRef.current?.focus();
  }

  navigation.addListener("focus", focusOnInput);

  return (
    <View>
      <TextInput ref={textInputRef} label="Account name" value={name} onChangeText={setName}/>
    </View>
  )
}
Ahmed Gaber
  • 3,384
  • 2
  • 12
  • 18
pta2002
  • 185
  • 1
  • 3
  • 12

1 Answers1

6

use React.useRef() instead of createRef();
use React.useEffect to listen when ref is defined to can use it.

export default function NewAccountScreen({ navigation }) {
  const [name, setName] = useState('');

  const textInputRef = React.useRef();

  React.useEffect(() => {
     if(textInputRef.current){
        const unsubscribe = navigation.addListener('focus', () => {
          textInputRef.current?.focus()
        });
       return unsubscribe;
     }
  }, [navigation, textInputRef.current]);

  return (
    <View>
      <TextInput ref={textInputRef} label="Account name" value={name} onChangeText={setName}/>
    </View>
  )
}

Update: as @pta2002 comment

I tried this, and it focuses sometimes now, but sometimes it seems to focus and then immediatelly unfocus...

i test the snack, and as he said it is already not working in some times!
Really I can't understand why?, but I try something, and it is work.

listen for transitionEnd not focus

try snack here

  React.useEffect(() => {
    if (textInputRef.current) {
      const unsubscribe = navigation.addListener('transitionEnd', () => {
        textInputRef.current?.focus();
      })

      return unsubscribe;
    }
  }, [navigation, textInputRef.current])

other solution work for me surround textInputRef.current?.focus(); with setTimeout with 1000 ms

  React.useEffect(() => {
    if (textInputRef.current) {
      const unsubscribe = navigation.addListener('focus', () => {
        setTimeout(() => {
           textInputRef.current?.focus();
        }, 1000);
      })

      return unsubscribe;
    }
  }, [navigation, textInputRef.current])
Ahmed Gaber
  • 3,384
  • 2
  • 12
  • 18
  • 1
    I tried this, and it focuses sometimes now, but sometimes it seems to focus and then immediatelly unfocus... – pta2002 Sep 10 '21 at 22:31
  • if you can add more code or create snack with the problem, please do. – Ahmed Gaber Sep 10 '21 at 22:35
  • 1
    Hm I rewrote the code here: https://snack.expo.dev/@pta2002/0745da and now it works... Guess I'll just use this – pta2002 Sep 10 '21 at 23:25
  • I honestly have no idea why it does not work, I copy-pasted this code into my app and it still does not work. I guess it must be something elsewhere – pta2002 Sep 10 '21 at 23:39
  • Update: I tried the same expo again, and this time it did not work, so I guess there's something wrong here still. Seems like it's something that only happens on the android version though. – pta2002 Sep 10 '21 at 23:54