Skip to content

Commit

Permalink
Fix KeyboardAvoidingView not aware of the keyboard closing after it i…
Browse files Browse the repository at this point in the history
…s unmounted (#46952)

Summary:
In the new architecture, if you open the soft keyboard, unmount `KeyboardAvoidingView`, close the keyboard, and then remount `KeyboardAvoidingView`, it still assumes the keyboard is open and displays the keyboard avoiding area.

We need to check if the keyboard is still open after remounting.

Fixes #46942

## Changelog:

[GENERAL] [FIXED] - Fix KeyboardAvoidingView not aware of the keyboard closing it is unmounted

Pull Request resolved: #46952

Test Plan:
Code to reproduce in RNTester:

```JSX
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import {Button, KeyboardAvoidingView, Text, TextInput, View} from 'react-native';
import {Fragment, Suspense, useState} from "react";

const infiniteThenable = { then() {} };

function Suspender({ freeze, children }) {
  if (freeze) {
    throw infiniteThenable;
  }
  return <Fragment>{children}</Fragment>;
}

function Freeze({ freeze, children }) {
  return (
    <Suspense>
      <Suspender freeze={freeze}>{children}</Suspender>
    </Suspense>
  );
}

function Playground() {
  const [isFrozen, setIsFrozen] = useState(false);

  return (
    <>
      <TextInput style={{ height: 100 }} />
      <Button title="Freeze" onPress={() => setIsFrozen(true)} />
      <Button title="Unfreeze" onPress={() => setIsFrozen(false)} />

      <Freeze freeze={isFrozen}>
        <KeyboardAvoidingView behavior="padding" style={{ flex: 1 }}>
          <View style={{ backgroundColor: '#909090', flex: 1, alignItems: 'center', justifyContent: 'flex-end' }}>
            <Text>Test</Text>
            <Text></Text>
          </View>
        </KeyboardAvoidingView>
      </Freeze>
    </>
  );
}

export default ({
  title: 'Playground',
  name: 'playground',
  render: (): React.Node => <Playground />,
}: RNTesterModuleExample);
```

### Steps

1. Tap the text input to show the soft keyboard.
2. Tap Freeze.
3. Tap the Enter or Done button on the soft keyboard to hide it.
4. Tap Unfreeze.
5. Verify that there is no blank area at the bottom of the screen.

### Videos

#### iOS

Before | After
-- | --
<video src="https://github.com/user-attachments/assets/0c8d840e-14a6-47ad-a163-d34ac9cfbf40" /> | <video src="https://github.com/user-attachments/assets/1d88a70c-e029-433d-920d-da7582edb3f2" />

#### Android

Before | After
-- | --
<video src="https://github.com/user-attachments/assets/f29f6526-c5a4-4b6a-b3aa-7c4c7ff3ed30" /> | <video src="https://github.com/user-attachments/assets/c4e92356-694b-4fca-8897-7dfca8495db0" />

Reviewed By: andrewdacenko

Differential Revision: D64178982

Pulled By: cipolleschi

fbshipit-source-id: 8d71654aac599cec4e1928b14d87cff34f28174a
  • Loading branch information
QichenZhu authored and facebook-github-bot committed Oct 15, 2024
1 parent 2c9176a commit 08bd8ac
Showing 1 changed file with 5 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
}

componentDidMount(): void {
if (!Keyboard.isVisible()) {
this._keyboardEvent = null;
this._setBottom(0);
}

if (Platform.OS === 'ios') {
this._subscriptions = [
Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
Expand Down

0 comments on commit 08bd8ac

Please sign in to comment.