diff --git a/src/components/CountryPicker/CountrySelectorModal.js b/src/components/CountryPicker/CountrySelectorModal.js index 126cea7e842e..e6ed1a77ce85 100644 --- a/src/components/CountryPicker/CountrySelectorModal.js +++ b/src/components/CountryPicker/CountrySelectorModal.js @@ -87,7 +87,6 @@ function CountrySelectorModal({currentCountry, isVisible, onClose, onCountrySele sections={[{data: searchResults, indexOffset: 0}]} onSelectRow={onCountrySelected} onChangeText={setSearchValue} - shouldDelayFocus initiallyFocusedOptionKey={currentCountry} /> diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index 046b64e9e5c0..b76ded8a542f 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -1,7 +1,8 @@ -import React, {useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import lodashGet from 'lodash/get'; +import {useFocusEffect} from '@react-navigation/native'; import SectionList from '../SectionList'; import Text from '../Text'; import styles from '../../styles/styles'; @@ -42,7 +43,6 @@ function BaseSelectionList({ keyboardType = CONST.KEYBOARD_TYPE.DEFAULT, onChangeText, initiallyFocusedOptionKey = '', - shouldDelayFocus = false, onScroll, onScrollBeginDrag, headerMessage = '', @@ -266,23 +266,20 @@ function BaseSelectionList({ ); }; - /** Focuses the text input when the component mounts. If `props.shouldDelayFocus` is true, we wait for the animation to finish */ - useEffect(() => { - if (shouldShowTextInput) { - if (shouldDelayFocus) { + /** Focuses the text input when the component comes into focus and after any navigation animations finish. */ + useFocusEffect( + useCallback(() => { + if (shouldShowTextInput) { focusTimeoutRef.current = setTimeout(() => textInputRef.current.focus(), CONST.ANIMATED_TRANSITION); - } else { - textInputRef.current.focus(); - } - } - - return () => { - if (!focusTimeoutRef.current) { - return; } - clearTimeout(focusTimeoutRef.current); - }; - }, [shouldDelayFocus, shouldShowTextInput]); + return () => { + if (!focusTimeoutRef.current) { + return; + } + clearTimeout(focusTimeoutRef.current); + }; + }, [shouldShowTextInput]), + ); /** Selects row when pressing Enter */ useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, selectFocusedOption, { diff --git a/src/components/SelectionList/selectionListPropTypes.js b/src/components/SelectionList/selectionListPropTypes.js index 9adf42833ebc..1a4fd6c5ecab 100644 --- a/src/components/SelectionList/selectionListPropTypes.js +++ b/src/components/SelectionList/selectionListPropTypes.js @@ -130,9 +130,6 @@ const propTypes = { /** Item `keyForList` to focus initially */ initiallyFocusedOptionKey: PropTypes.string, - /** Whether to delay focus on the text input when mounting. Used for a smoother animation on Android */ - shouldDelayFocus: PropTypes.bool, - /** Callback to fire when the list is scrolled */ onScroll: PropTypes.func, diff --git a/src/components/StatePicker/StateSelectorModal.js b/src/components/StatePicker/StateSelectorModal.js index c7cbd5be9e31..ae8d3efdd27e 100644 --- a/src/components/StatePicker/StateSelectorModal.js +++ b/src/components/StatePicker/StateSelectorModal.js @@ -92,7 +92,6 @@ function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, sections={[{data: searchResults, indexOffset: 0}]} onSelectRow={onStateSelected} onChangeText={setSearchValue} - shouldDelayFocus initiallyFocusedOptionKey={currentState} /> diff --git a/src/pages/settings/Profile/PronounsPage.js b/src/pages/settings/Profile/PronounsPage.js index 4fa97a74d061..5ce9957f568f 100644 --- a/src/pages/settings/Profile/PronounsPage.js +++ b/src/pages/settings/Profile/PronounsPage.js @@ -80,7 +80,6 @@ function PronounsPage({currentUserPersonalDetails}) { onSelectRow={updatePronouns} onChangeText={setSearchValue} initiallyFocusedOptionKey={currentPronounsKey} - shouldDelayFocus /> ); diff --git a/src/pages/settings/Profile/TimezoneSelectPage.js b/src/pages/settings/Profile/TimezoneSelectPage.js index c4fdda42114f..58a45f729e17 100644 --- a/src/pages/settings/Profile/TimezoneSelectPage.js +++ b/src/pages/settings/Profile/TimezoneSelectPage.js @@ -90,7 +90,6 @@ function TimezoneSelectPage(props) { onSelectRow={saveSelectedTimezone} sections={[{data: timezoneOptions, indexOffset: 0, isDisabled: timezone.automatic}]} initiallyFocusedOptionKey={_.get(_.filter(timezoneOptions, (tz) => tz.text === timezone.selected)[0], 'keyForList')} - shouldDelayFocus showScrollIndicator /> diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index b7a1986c06e6..e37588d2d401 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -227,7 +227,6 @@ function WorkspaceInvitePage(props) { onSelectRow={toggleOption} onConfirm={inviteUser} showScrollIndicator - shouldDelayFocus showLoadingPlaceholder={!didScreenTransitionEnd || !OptionsListUtils.isPersonalDetailsReady(props.personalDetails)} /> diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index d598f90e4326..53ddd0fb5d96 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -393,7 +393,6 @@ function WorkspaceMembersPage(props) { onSelectAll={() => toggleAllUsers(data)} onDismissError={dismissError} showLoadingPlaceholder={!OptionsListUtils.isPersonalDetailsReady(props.personalDetails) || _.isEmpty(props.policyMembers)} - shouldDelayFocus showScrollIndicator /> diff --git a/tests/perf-test/SelectionList.perf-test.js b/tests/perf-test/SelectionList.perf-test.js index 82cec956713f..d16875e31357 100644 --- a/tests/perf-test/SelectionList.perf-test.js +++ b/tests/perf-test/SelectionList.perf-test.js @@ -29,6 +29,11 @@ jest.mock('../../src/components/withKeyboardState', () => (Component) => (props) /> )); +jest.mock('@react-navigation/native', () => ({ + useFocusEffect: () => {}, + createNavigationContainerRef: jest.fn(), +})); + function SelectionListWrapper(args) { const [selectedIds, setSelectedIds] = useState([]);