How to detect when keyboard is opened or closed in React Native

Solution 1:

Thank you guys for your answers. Here is the hooks version if someone is interested:

const [isKeyboardVisible, setKeyboardVisible] = useState(false);

 useEffect(() => {
    const keyboardDidShowListener = Keyboard.addListener(
      'keyboardDidShow',
      () => {
        setKeyboardVisible(true); // or some other action
      }
    );
    const keyboardDidHideListener = Keyboard.addListener(
      'keyboardDidHide',
      () => {
        setKeyboardVisible(false); // or some other action
      }
    );

    return () => {
      keyboardDidHideListener.remove();
      keyboardDidShowListener.remove();
    };
  }, []);

Solution 2:

1. You can use Keyboard class from facebook.

Here is a sample code.

import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';

class Example extends Component {
  componentWillMount () {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
  }
    
  componentWillUnmount () {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
  }
    
  _keyboardDidShow () {
    alert('Keyboard Shown');
  }
    
  _keyboardDidHide () {
    alert('Keyboard Hidden');
  }
    
  render() {
    return (
      <TextInput
        onSubmitEditing={Keyboard.dismiss}
      />
    );
  }
}

###2. You can use some other npm dependency also, like react-native-keyboard-listener.

Import the component into the file you want to use it:

import KeyboardListener from 'react-native-keyboard-listener';

Use the component directly in your code. The component won't render anything

<View>
  <KeyboardListener
    onWillShow={() => { this.setState({ keyboardOpen: true }); }}
    onWillHide={() => { this.setState({ keyboardOpen: false }); }}
  />
</View>

To install this dependency run below command.

npm install --save react-native-keyboard-listener

Choose any you feel more convenient.

Solution 3:

Custom Hook:

import { useEffect, useState } from 'react';
import { Keyboard } from 'react-native';

export function useKeyboard() {
  const [isKeyboardVisible, setKeyboardVisible] = useState(false);

  useEffect(() => {
    const keyboardDidShowListener = Keyboard.addListener(
      'keyboardDidShow',
      () => {
        setKeyboardVisible(true); // or some other action
      },
    );
    const keyboardDidHideListener = Keyboard.addListener(
      'keyboardDidHide',
      () => {
        setKeyboardVisible(false); // or some other action
      },
    );

    return () => {
      keyboardDidHideListener.remove();
      keyboardDidShowListener.remove();
    };
  }, []);

  return isKeyboardVisible;
}

Usage:

import { useKeyboard } from './useKeyboard';
    
const isKeyBoardOpen = useKeyboard();

Solution 4:

Improved version of @Khemraj 's answer (which worked great for me) with bound methods to the instance in order to be able to update the component's state from the listener and re-render.

import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';

class Example extends Component {

  state = {
      keyboardState: 'closed'
  }

  componentWillMount () {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
  }

  componentWillUnmount () {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
  }

  _keyboardDidShow = () => {
    this.setState({
        keyboardState: 'opened'
    });
  }

  _keyboardDidHide = () => {
    this.setState({
        keyboardState: 'closed'
    });
  }

  render() {
    return (
      <TextInput
        onSubmitEditing={Keyboard.dismiss}
      />
    );
  }
}

Solution 5:

I came across the usekeyboard hook found in @react-native-community/hooks

E.g.

import { useKeyboard } from '@react-native-community/hooks'

const keyboard = useKeyboard()

console.log('keyboard isKeyboardShow: ', keyboard.keyboardShown)
console.log('keyboard keyboardHeight: ', keyboard.keyboardHeight)

Source: https://github.com/react-native-community/hooks/blob/master/src/useKeyboard.ts