KeyboardAvoidingView - Reset height when Keyboard is hidden

Wrap components in <KeyboardAvoidingView behavior="padding" style={styles}> on iOS and <View style={styles}> on android

render() {
    const ScrollContainer: View | KeyboardAvoidingView = 
    this.renderDependingOnPlatform();
    const scrollContainerParams: any = {};
    if (isIOS)
        scrollContainerParams.behavior = "padding";
return (
<ScrollContainer style={styles.container} {...scrollContainerParams}>
Scroll and other components
</ScrollContainer>
)}

/**
 * Render scroll container depending on platform
 * @returns {any}
 */
renderDependingOnPlatform() {
    if (isAndroid())
        return View;
    else return KeyboardAvoidingView;
}

Please give key to KeyboardAvoidingView and change when keyboard open and close so it will render and take height

<KeyboardAvoidingView behavior="height" style={styles.step} key={values}>

A more detailed explanation on Nisarg's answer.

Create a key for the KeyboardAvoidingView in the constructor

constructor(props) {
    this.state = {
      keyboardAvoidingViewKey: 'keyboardAvoidingViewKey',
    }
}

add listener on the keyboard's will/did hide (and remove it in the willUnmount)

import { KeyboardAvoidingView, Keyboard, Platform } from 'react-native'

componentDidMount() {
    // using keyboardWillHide is better but it does not work for android
    this.keyboardHideListener = Keyboard.addListener(Platform.OS === 'android' ? 'keyboardDidHide': 'keyboardWillHide', this.keyboardHideListener.bind(this));
}

componentWillUnmount() {
    this.keyboardHideListener.remove()
}

update the keyboardAvoidingViewKey in the keyboardHideListener function, should be a new value each time (I used a timestamp) and use this key when rendering the KeyboardAvoidingView element.

keyboardHideListener() {
    this.setState({
        keyboardAvoidingViewKey:'keyboardAvoidingViewKey' + new Date().getTime()
    });
}

render() {
    let { keyboardAvoidingViewKey } = this.state
    return (
        <KeyboardAvoidingView behavior={'height'} key={keyboardAvoidingViewKey} style={...}>
            ...
        </KeyboardAvoidingView>
    )
}

Note: Keep in mind that this will recreate the elements inside the KeyboardAvoidingView (i.e: will call their constructor function, I'm not quite sure why, I'll update the answer after deeper investigation), so you'll have to keep track of any state/prop values that might be overwritten

Update

After a much deeper investigation, I now know why the views are recreated once you change the key. In order to truly understand why it happens, one must be familiar with how react-native dispatches the render commands to the native side, this particular explanation is pretty long, if it interests you, you can read my answer here. In short, react-native uses Reactjs to diff the changes that should be rendered, these diffs are then sent as commands to a component named UIManager, which sends imperative commands that translate into a layout tree, which changes the layout based on the diff commands. Once you set a key on a component, reactjs uses this key to identify changes to said component, if this key changes, reactjs identifies the component as a completely new one, which in return sends the initial command to create said component, making all it's children to be created from scratch because there are identified as new elements in a new layout tree, deleting the old tree and creating a new one instead of just adjusting the diffs

If you would like, you can actually spy on these dispatched messages by adding the following code to your App.js file:

import MessageQueue from 'react-native/Libraries/BatchedBridge/MessageQueue'
const spyFunction = (msg) => {
    console.log(msg);
};

MessageQueue.spy(spyFunction);

If you do that, you'll notice in the logs that each time the key changes, the command that is dispatched in return is createViews, which like stated above creates all the elements that are nested under said component.