'How to get a height of a Keyboard in React-Native?
I am using React-Navigation in my app and the app consists of StackNavigator with multiple screens, some screens of which have TextInput with autoFocus={true}
Problem: on these screens when the component renders, the height of the screen is being set in the constructor:
constructor(props) {
super(props);
this.state = {
height: Dimensions.get('window').height,
};
}
But, since the autoFocus of TextInput is true, the keyboard on this screen pops-up on the screen almost instantly after the render, causing the component to re-render due to the eventListener that is added to Keyboard in componentWillMount:
componentWillMount() {
this.keyboardWillShowListener = Keyboard.addListener(
"keyboardWillShow",
this.keyboardWillShow.bind(this)
);
}
keyboardWillShow(e) {
this.setState({
height:
Dimensions.get("window").height * 0.9 - e.endCoordinates.height
});
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
}
This affects the performance and I would like to avoid the unnecessary re-renders.
Questions:
1. Is it possible to set the dynamic height (depending on the device) of the Keyboard in React-Navigation's ScreenProps?
2. Is it possible to do the same with React-Navigation's state.params?
3. Is there any other way to solve this problem, apart from applying KeyboardAvoidingView or this module ?
Solution 1:[1]
I also needed a hook for it, so that is how I get the height of the keyboard (largely inspired by the other answer), the code example is in TypeScript:
import { useEffect, useState } from 'react';
import { Keyboard, KeyboardEvent } from 'react-native';
export const useKeyboard = () => {
const [keyboardHeight, setKeyboardHeight] = useState(0);
function onKeyboardDidShow(e: KeyboardEvent) { // Remove type here if not using TypeScript
setKeyboardHeight(e.endCoordinates.height);
}
function onKeyboardDidHide() {
setKeyboardHeight(0);
}
useEffect(() => {
const showSubscription = Keyboard.addListener('keyboardDidShow', onKeyboardDidShow);
const hideSubscription = Keyboard.addListener('keyboardDidHide', onKeyboardDidHide);
return () => {
showSubscription.remove();
hideSubscription.remove();
};
}, []);
return keyboardHeight;
};
then in your component:
const keyboardHeight = useKeyboard();
console.log(keyboardHeight);
Solution 2:[2]
For those of you still looking for an answer to this now you can use hooks.
import { useKeyboard } from '@react-native-community/hooks'
//Then keyboard like this
const keyboard = useKeyboard()
console.log('keyboard isKeyboardShow: ', keyboard.keyboardShown)
console.log('keyboard keyboardHeight: ', keyboard.keyboardHeight)
Solution 3:[3]
Just would like to add to the above answers, that using keyboardWillShow and keyboardWillHide rather than keyboardDidShow and keyboardDidHide will look much better. It just runs sooner and hence, looks smoother.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Lazerbeak12345 |
| Solution 3 |
