React-native-screens: Keyboard doesn't show up when autoFocus on component mount

Created on 20 Apr 2019  路  32Comments  路  Source: software-mansion/react-native-screens

Hello,

I am trying to use react-native-screens combine with react-navigation for my app for better performance, however I have a weird problem. Indeed, when I have a new page mounting with a TextInput set on autoFocus, it focused as expected but the keyboard does not show up on the screen.

If I don't put useScreens() it works perfectly, the TextInput is focused and the Keyboard appears.

react-native: 0.59.1;
react-navigation: 3.8.1;
react-native-screens: 1.0.0-alpha.22;
OS: Android;
Device: Real;

Most helpful comment

Same problem here.

I'm using a settimeout in componentdidmount to trigger the focus after some milliseconds, but still not the best because there is a necessary delay.
setTimeout(() => this.ref.focus(), 150)
Remove autoFocus prop on the component or else it won't work.

Looking forward to a better solution if possible.

All 32 comments

Same problem on all platforms and simulators?
I guess you could workaround it by using a ref to the TextInputand calling .focus() but it should work out of the box with autofocus too.

I am seeing this, as well, on Android. iOS is working fine. If I push a screen onto a React Navigation StackNavigator, and autoFocus is set on a TextInput, the TextInput is focused, but the keyboard does not pop up (or maybe it pops up and is immediately dismissed, hard to tell). If I don't call useScreens() on Android, then I have no issue.

react-native-screen: 1.0.0-alpha.22
react-navigation: 3.8.0
Expo: SDK 31
Android: 8.0 / Galaxy S8 (device)

@mifi Indeed it is possible to make a work around with .focus() and DidFocus(); with NavigationEvents, but the user experience is not the same at all since it takes around 0.5-1s to show the keyboard giving the impression that the app is lagging, whereas with autoFocus, the keyboard pop up straight away.

Yea, it seems this project has quite a few issues compared to plain View-based screens that need to resolved. Everything is more complicated in Native code than in JS.

I see the same on my Pixel 2 (Android 9.0).

Bump?

This issue is pretty significant for user experience. I may take care of it later this year if it's not fixed by then.

@Palid any ideas in mind where the problem is and possible fixes?

My idea is that because it's creating a new native view it just doesn't propagate focus event properly on Android. Haven't researched it properly yet, though.

Any updates for this problem? I have this problem in Android.

I have tried to use autoFocus and ref, but it didn't help. What workarounds did you use?

```
componentDidMount() {
this.ref.focus();
}

ref={ref => this.ref = ref}
autoFocus={true}
value={this.props.reflection}
onChange={ e => this.props.onChange('reflection', e) }
/>

```

Any updates for this problem? I have this problem in Android.

I have tried to use autoFocus and ref, but it didn't help. What workarounds did you use?

componentDidMount() {
       this.ref.focus();
   }

<TextInput
                           ref={ref => this.ref = ref}
                           autoFocus={true}
                           value={this.props.reflection}
                           onChange={ e => this.props.onChange('reflection', e) }
                       />  

Me too ^^^

any workarounds for this?

Same problem here.

I'm using a settimeout in componentdidmount to trigger the focus after some milliseconds, but still not the best because there is a necessary delay.
setTimeout(() => this.ref.focus(), 150)
Remove autoFocus prop on the component or else it won't work.

Looking forward to a better solution if possible.

react-navigation NavigationEvents component seems to also work using the onDidFocus prop, but it feels slower than using the setTimout like above.

<>
        <NavigationEvents onDidFocus={() => this.refs.searchbar.focus()} />
        <Searchbar
          ref="searchbar"
          placeholder="Search"
          onChangeText={this._handleChangeText}
          value={this.state.searchTerms}
        />
</>

Can you try 2.0.0-alpha3? This https://github.com/kmagiera/react-native-screens/pull/152/files should solve the issue.

@ferrannp I had the same problem and can confirm that 2.0.0-alpha.3 fixes this issue.

I confirm that with 2.0.0-alpha3 it works now ! Sorry for answering so late but I had to update all my react-native package to use 2.0.0-alpha3 version.

@AlexandreMaistret its mentioned in reactnavigation docs to install react-native-screens@^1.0.0-alpha.23 so I'm not sure what I have to do to upgrade react-native-screens and why they are recommending this particular version!

Can this be backported to 1.0 as well for people who are still RN < 0.60.....

@mnzaki people with RN < 0.60 can probably use something like patch-package to manually modify and maintain changes while using older version of library.

Same problem here.

I'm using a settimeout in componentdidmount to trigger the focus after some milliseconds, but still not the best because there is a necessary delay.
setTimeout(() => this.ref.focus(), 150)
Remove autoFocus prop on the component or else it won't work.

Looking forward to a better solution if possible.

I was able to get this to work using a shortened timer (50ms), thank you to the workaround above.

Platform.OS === "ios" ? this.ref.focus() : setTimeout(() => this.ref.focus(), 50)

I would like to avoid using things like patch-package, too many moving parts for my taste....
Also it is rather straightforward to backport this fix for now: https://github.com/jolocom/react-native-screens/tree/fix_1.0_soft_keyboard
This can be installed using yarn add jolocom/react-native-screens#1.0.0-alpha.24

This branch works for me, and I am wondering if it is possible to PR it and release a 1.0-alpha.24 version? @kmagiera @ferrannp thoughts?

2.0-alpha is compatible with 1.0-alpha in terms of react-navigation integration. You should be safe to upgrade to 2.0 where I believe the issue has been fixed

The problem is with androidx. A lot of projects are still not androidx compatible, and moving to 2.0 forces androidx

I personally am still seeing this issue with 2.0.0-alpha.17 && react-navigation: 4.0.10 on Android devices.

mind preparing a minimal app that demonstrates how the issue can be reproduced @iamgerardm ?

400ms only working for me

Platform.OS === "ios" ? this.ref.focus() : setTimeout(() => this.ref.focus(), 400)

Still not working on :
"react-native-screens": "^2.7.0",
"react-navigation": "^4.3.8",

Had the same issue.
react-native-screens upgrading didn't help.

Solved it by removing autoFocus={true} and setting timeout.
I have a popup as a functional component and using "current.focus()" with Refs like this:

const Popup = ({
  placeholder,
  autoFocus,
  showStatus,
}) => {
  const inputRef = useRef(null);
  useEffect(() => {
     Platform.OS === 'ios'
        ? inputRef.current.focus()
        : setTimeout(() => inputRef.current.focus(), 40);
  }, [showStatus]);
  return (
    <View style={styles.inputContainer}>
      <TextInput
        style={styles.inputText}
        defaultValue={placeholder}
        ref={inputRef}
      />
    </View> 
};

I solved the problem by showing TextInput only in focused screen. In other words, re-show TextInput fire auto focus.

  const [isFocused, setIsFocued] = React.useState(true)

  const setFocus = React.useCallback(() => {
    setIsFocued(true)
  }, [])

  const setBlur = React.useCallback(() => {
    setIsFocued(false)
  }, [])

  const navi = useNavigation()

  React.useEffect(() => {
    navi.addListener('focus', setFocus)
    navi.addListener('blur', setBlur)
    return () => {
      navi.removeListener('focus', setFocus)
      navi.removeListener('blur', setBlur)
    }
  }, [])

  return (
    <View>
        {focused && <TextInput autoFocus />}
    </View>
  )
const _input = useRef();

  useEffect(() => {
    setTimeout(() => {
      _input.current.input.focus();
    }, 400);
  });


<Input
        ref={_input}
        placeholder="Say something about this..."
        inputStyle={style.inputShareStyle}
        inputContainerStyle={{borderBottomWidth: 0}}
        placeholderTextColor="#90949c"
      />

make sure in android you removed autofocus

For anyone looking for some typescript implementation

const MyTextInput = ({ autoFocus, ...props }: TextInputProps) => {
  const ref = useRef<TextInput>(null);

  useEffect(() => {
    autoFocus &&
      setTimeout(() => {
        if (ref.current) {
          ref.current.focus();
        }
      }, 40);
  });

  return <TextInput ref={ref} {...props} />;
};

Here it's working with InteractionManager:

useEffect(() => {
    if (autoFocus  && inputRef.current) {
      if (inputRef.current) {
        InteractionManager.runAfterInteractions(() => {
          inputRef.current?.focus();
        });
      }
    }
  }, [autoFocus, inputRef]);

Hello,

I am trying to use react-native-screens combine with react-navigation for my app for better performance, however I have a weird problem. Indeed, when I have a new page mounting with a TextInput set on autoFocus, it focused as expected but the keyboard does not show up on the screen.

If I don't put useScreens() it works perfectly, the TextInput is focused and the Keyboard appears.

react-native: 0.59.1;
react-navigation: 3.8.1;
react-native-screens: 1.0.0-alpha.22;
OS: Android;
Device: Real;

if you are using Visual Studio, go to I/O -> keyboard-> toggle software keyboard. The keyboard should appear. And for it to disappear use this :
import {Keyboard} from 'react-native'

`import {Keyboard} from 'react-native'



`

Was this page helpful?
0 / 5 - 0 ratings