Development of Search with Autocomplete in Mobile Application
Search with autocomplete — component user notices only when it works badly: suggestions appear with delay, not filtered by relevance, on-screen keyboard covers results, or fast typing returns response for previous query instead of current. Right implementation from first attempt harder than looks.
Key technical tasks
Debounce and request cancellation. Each key tap shouldn't go to server. Standard scheme: debounce 250–350 ms + cancel previous request on new input. In React Native — useRef for timer storage + AbortController for fetch, or cancelToken in axios. On Flutter — StreamTransformer.fromHandlers + switchMap in Dart streams, or via Debouncer with Timer.cancel(). On Android with coroutines — flow.debounce(300) + flatMapLatest ensure only one request in flight.
Race conditions. User types "nike", gets request for "nike", then deletes to "ni" and adds "ke" again. If server answered "ni" request later than "nike", interface shows irrelevant suggestions. Solution: assign unique id to each request and ignore responses with stale id.
Keyboard and layout. On iOS KeyboardAvoidingView with behavior="padding" works correctly only with correct keyboardVerticalOffset. On Android — android:windowSoftInputMode="adjustResize" in manifest, otherwise suggestions list goes under keyboard. On Flutter — Scaffold automatically handles resizeToAvoidBottomInset, but if SearchBar in custom overlay — need to listen MediaQuery.of(context).viewInsets.bottom manually.
Component architecture
Search screen has three states: empty input (show search history or popular queries), loading (skeleton or indicator), results received (list of suggestions or "nothing found").
Search history — in AsyncStorage (RN) or SharedPreferences (Android) / UserDefaults (iOS). Maximum 10–15 last queries, deduplicate by text, show with clock icon.
For highlighting matches in suggestion text use split by entered string + <Text> with different style on match. Not regexp replace — breaks on special characters in query.
Case from practice: marketplace, React Native, search by 200,000 products. Complaints: "suggestions stale". Analysis showed — responses came with different delays (CDN cached popular requests fast, rare — slow), and without canceling stale requests interface flickered with random results. Added AbortController + requestId tracking — problem gone completely.
Local search
For small datasets (< 5,000 records) search can be client-side. On Flutter — fuse_dart package (fuzzy search). In RN — fuse.js. On Android — Room FTS4 for SQLite full-text search. Removes network delays and works offline.
What's included
- SearchBar with focus animation and clear button
- Autocomplete list with match highlighting
- Search history with delete ability
- Debounce + cancel stale requests
- State handling: loading, empty result, error
- Keyboard type (
search,doneaction on button) - Optional: voice search via SpeechRecognizer (Android) / SFSpeechRecognizer (iOS)
Timeline
2–3 working days — basic implementation with API autocomplete, history and edge case handling. Cost calculated individually.







