Skip to content

Migrate useSearchSelector.base.ts from useOptionsList to useFilteredOptions #82191

@mountiny

Description

@mountiny

Problem

useSearchSelector.base.ts currently uses the useOptionsList hook from OptionListContextProvider, which causes unnecessary background recalculations on every personal details or reports change.

This is part of a larger effort to remove OptionListContextProvider entirely. See parent issue #82193 for full context.

Solution

Replace useOptionsList with useFilteredOptions following the pattern established in PR #74071 (NewChatPage migration).

Current usage:

  • Properties used: options (as defaultOptions), areOptionsInitialized
  • Called with: { shouldInitialize } (from hook config, defaults to true)
  • File: src/hooks/useSearchSelector.base.ts

How options are used:

  • options (renamed to defaultOptions) is merged with contactOptions into optionsWithContacts
  • Used as base for baseOptions in switch on searchContext (via getSearchOptions or getValidOptions)
  • areOptionsInitialized guards optionsWithContacts and baseOptions computation
  • areOptionsInitialized is exposed in the return value for consumers

High-impact migration: This is a shared base hook used indirectly by approximately 10 screens:

  • VacationDelegatePage
  • MoneyRequestParticipantsSelector
  • MoneyRequestAttendeeSelector
  • BaseOnboardingWorkspaceInvite
  • WorkspaceInvitePage
  • InviteReportParticipantsPage
  • AssigneeStep (Expensify Card)
  • AssigneeStep (Company Cards)
  • TaskAssigneeSelectorModal
  • BaseShareLogList

Migrating this hook automatically benefits all these indirect consumers.

Migration steps:

  1. Replace import {useOptionsList} from '@components/OptionListContextProvider' with import useFilteredOptions from '@hooks/useFilteredOptions'
  2. Replace useOptionsList({ shouldInitialize }) with useFilteredOptions({ enabled: shouldInitialize }) (or a similar mapping)
  3. Replace areOptionsInitialized with !isLoading (or options !== null)
  4. Update optionsWithContacts and baseOptions guards accordingly
  5. Update the return value to expose the new loading semantics
  6. Verify all ~10 indirect consumers still work correctly

Complexity: Medium (high-impact due to ~10 indirect consumers)

Reference PR: #74071

Tests

  • Verify search selector works across all screens that use useSearchSelector:
    • MoneyRequestParticipantsSelector (create expense > select participant)
    • WorkspaceInvitePage (workspace settings > invite members)
    • InviteReportParticipantsPage (report > invite participants)
    • TaskAssigneeSelectorModal (assign a task)
    • VacationDelegatePage (vacation delegate selection)
    • And other indirect consumers listed above
  • Verify loading placeholders show correctly while options compute
  • Verify search/filter functionality works in each context
  • Verify no errors appear in the JS console
  • Test on all platforms (iOS, Android, Web, Desktop)
Issue OwnerCurrent Issue Owner: @hoangzinh

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions