diff --git a/packages/base/src/SearchBar/SearchBar-android.tsx b/packages/base/src/SearchBar/SearchBar-android.tsx index 342b7418ac..6dcd1b20d9 100644 --- a/packages/base/src/SearchBar/SearchBar-android.tsx +++ b/packages/base/src/SearchBar/SearchBar-android.tsx @@ -5,6 +5,7 @@ import { ActivityIndicator, Keyboard, TextInput, + EmitterSubscription, } from 'react-native'; import { defaultTheme, renderNode } from '../helpers'; import { Input, InputProps } from '../Input'; @@ -49,7 +50,7 @@ export class SearchBarAndroid extends Component< SearchBarState > { input!: TextInput; - _keyboardDidHideListener; + static defaultProps = { onClear: () => null, onCancel: () => null, @@ -58,6 +59,8 @@ export class SearchBarAndroid extends Component< onChangeText: () => null, }; + keyboardListener: EmitterSubscription; + focus = () => { this.input.focus(); }; @@ -102,7 +105,7 @@ export class SearchBarAndroid extends Component< hasFocus: false, isEmpty: value ? value === '' : true, }; - this._keyboardDidHideListener = Keyboard.addListener( + this.keyboardListener = Keyboard.addListener( 'keyboardDidHide', this._keyboardDidHide ); @@ -112,7 +115,9 @@ export class SearchBarAndroid extends Component< }; componentWillUnmount() { - this._keyboardDidHideListener.remove(); + if (this.keyboardListener) { + this.keyboardListener.remove(); + } } render() { diff --git a/packages/base/src/SearchBar/__tests__/SearchBar.test.tsx b/packages/base/src/SearchBar/__tests__/SearchBar.test.tsx index 297eac853d..2d5723b1d2 100644 --- a/packages/base/src/SearchBar/__tests__/SearchBar.test.tsx +++ b/packages/base/src/SearchBar/__tests__/SearchBar.test.tsx @@ -1,6 +1,7 @@ import React from 'react'; import SearchBar from '../index'; import { renderWithWrapper } from '../../../.ci/testHelper'; +import { Keyboard } from 'react-native'; describe('SearchBar wrapper component', () => { it('should match snapshot', () => { @@ -37,4 +38,33 @@ describe('SearchBar wrapper component', () => { ); expect(component.toJSON()).toMatchSnapshot(); }); + + describe('keyboard eventListener', () => { + const mockListener = { + remove: jest.fn(), + }; + const originalAddListener = Keyboard.addListener; + const mockAddListener = jest.fn().mockReturnValue(mockListener); + + beforeAll(() => { + Keyboard.addListener = mockAddListener; + }); + beforeEach(() => { + mockAddListener.mockClear(); + mockListener.remove.mockClear(); + }); + afterAll(() => { + Keyboard.addListener = originalAddListener; + }); + it('should subscribe to KeyboardDidClose event', () => { + renderWithWrapper(); + expect(Keyboard.addListener).toHaveBeenCalled(); + }); + + it('should call listener.remove on unmount', () => { + const component = renderWithWrapper(); + component.unmount(); + expect(mockListener.remove).toHaveBeenCalled(); + }); + }); });