_reactNative.Keyboard.removeListener is not a function

Viewed 4753

I just upgraded from RN 0.63.2 to 0.64.2 then to 0.65.0-rc.3. Now I started to get this exception while trying to navigate between screens: _reactNative.Keyboard.removeListener is not a function.

enter image description here

The problem seems to be in BottomTabBar.js. The code snippet is below.

enter image description here

The React-navigation version is 4.4.0. React-navigation-tabs version is 1.2.0.

I checked the Keyboard class' methods and actually, I CAN see a method called "removeListener". Even the auto-complete shows it.

enter image description here

Also, I can see in the react-native documentation that this method exists:

enter image description here

So, I don't see why I am getting this exception. Any help is much appreciated.

Updating the react-navigation version could be a solution, not sure about that, but I would like to avoid that path if possible since it has been working perfectly till now.

Thanks.

Edit: Just realized this exception is not thrown when navigating to a screen for the first time. It is thrown when I revisit a screen that has been previously visited.

Edit2: I am seeing this behavior on android. Haven't been able to compile the project on iOS yet.

Edit3: npm list react-native-tab-view command shows different versions for react-native-tab-view

├── react-native-tab-view@2.15.1
├─┬ react-navigation-drawer@1.4.0
│ └── react-native-tab-view@1.4.1
└─┬ react-navigation-tabs@1.2.0
  └── react-native-tab-view@1.4.1

I did npm install react-native-tab-view@1.4.1 but nothing changed. I mean the output of the above npm list command changed and it all showed version 1.4.1 for react-native-tab-view but the behavior did not change.

3 Answers

removeListener method has been deprecated. It is suggested to call remove on the subscriptionEvent rather than calling removeListener.

Replace those lines as follows and use patch-package to commit your changes -

   componentDidMount() {
     if (Platform.OS === 'ios') {
        this.keyboardWillShow = Keyboard.addListener('keyboardWillShow', this._handleKeyboardShow);
        this.keyboardWillHide = Keyboard.addListener('keyboardWillHide', this._handleKeyboardHide);
     } else {
        this.keyboardDidShow = Keyboard.addListener('keyboardDidShow', this._handleKeyboardShow);
        this.keyboardDidHide = Keyboard.addListener('keyboardDidHide', this._handleKeyboardHide);
     }
   }
 
   componentWillUnmount() {
     if (Platform.OS === 'ios') {
        this.keyboardWillShow?.remove();
        this.keyboardWillHide?.remove();
     } else {
        this.keyboardDidShow?.remove();
        this.keyboardDidHide?.remove();
     }
   }

This fixed my issue:

modify node_modules/react-native-gifted-chat/lib/MessageContainer.js

this.attachKeyboardListeners = () => {
    const { invertibleScrollViewProps: invertibleProps } = this.props;
    if (invertibleProps) {
-        Keyboard.addListener('keyboardWillShow', invertibleProps.onKeyboardWillShow);
-        Keyboard.addListener('keyboardDidShow', invertibleProps.onKeyboardDidShow);
-        Keyboard.addListener('keyboardWillHide', invertibleProps.onKeyboardWillHide);
-        Keyboard.addListener('keyboardDidHide', invertibleProps.onKeyboardDidHide);
+        this.willShowSub = Keyboard.addListener('keyboardWillShow', invertibleProps.onKeyboardWillShow);
+        this.didShowSub = Keyboard.addListener('keyboardDidShow', invertibleProps.onKeyboardDidShow);
+        this.willHideSub = Keyboard.addListener('keyboardWillHide', invertibleProps.onKeyboardWillHide);
+        this.didHideSub = Keyboard.addListener('keyboardDidHide', invertibleProps.onKeyboardDidHide);
    }
};
this.detachKeyboardListeners = () => {
    const { invertibleScrollViewProps: invertibleProps } = this.props;
-    Keyboard.removeListener('keyboardWillShow', invertibleProps.onKeyboardWillShow);
-    Keyboard.removeListener('keyboardDidShow', invertibleProps.onKeyboardDidShow);
-    Keyboard.removeListener('keyboardWillHide', invertibleProps.onKeyboardWillHide);
-    Keyboard.removeListener('keyboardDidHide', invertibleProps.onKeyboardDidHide);
+    this.willShowSub?.remove();
+    this.didShowSub?.remove();
+    this.willHideSub?.remove();
+    this.didHideSub?.remove();
};

then, run:

# run patch-package to create a .patch file
npx patch-package react-native-gifted-chat
# commit the patch file to share the fix with your team
git add patches/some-package+0.16.3.patch
git commit -m "fix MessageContainer.js in react-native-gifted-chat"

Based on this response: https://github.com/FaridSafi/react-native-gifted-chat/issues/2090#issuecomment-901812607

I solved this modifying the file in node_modules/react-native/Libraries/Components/Keyboard/Keyboard.js and persisting the change using the patch-package library

You need rename the removeEventListener function to removeListener

Then you run in the project folder:

yarn patch-package react-native

This will create a patches folder in the root and a file with the changes. That's it.

Related