Skip to content

Commit c9ea05f

Browse files
committed
fix: prevent unwanted suggestions fetch after clear button tap (in Expo only)
1 parent 7887740 commit c9ea05f

File tree

1 file changed

+42
-37
lines changed

1 file changed

+42
-37
lines changed

src/GooglePlacesTextInput.js

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
import React, {
2-
useState,
3-
useRef,
4-
useEffect,
52
forwardRef,
3+
useEffect,
64
useImperativeHandle,
5+
useRef,
6+
useState,
77
} from 'react';
88
import {
9-
View,
10-
TextInput,
11-
FlatList,
12-
Text,
13-
TouchableOpacity,
14-
StyleSheet,
159
ActivityIndicator,
16-
Keyboard,
10+
FlatList,
1711
I18nManager,
12+
Keyboard,
1813
Platform,
14+
StyleSheet,
15+
Text,
16+
TextInput,
17+
TouchableOpacity,
18+
View,
1919
} from 'react-native';
2020

2121
// Import the API functions
2222
import {
23-
fetchPredictions as fetchPredictionsApi,
2423
fetchPlaceDetails as fetchPlaceDetailsApi,
24+
fetchPredictions as fetchPredictionsApi,
2525
generateUUID,
2626
isRTLText,
2727
} from './services/googlePlacesApi';
@@ -62,6 +62,7 @@ const GooglePlacesTextInput = forwardRef(
6262
const debounceTimeout = useRef(null);
6363
const inputRef = useRef(null);
6464
const suggestionPressing = useRef(false);
65+
const skipNextFocusFetch = useRef(false);
6566

6667
const generateSessionToken = () => {
6768
return generateUUID();
@@ -97,6 +98,10 @@ const GooglePlacesTextInput = forwardRef(
9798
// Expose methods to parent through ref
9899
useImperativeHandle(ref, () => ({
99100
clear: () => {
101+
if (debounceTimeout.current) {
102+
clearTimeout(debounceTimeout.current);
103+
}
104+
skipNextFocusFetch.current = true;
100105
setInputText('');
101106
setPredictions([]);
102107
setShowSuggestions(false);
@@ -185,27 +190,26 @@ const GooglePlacesTextInput = forwardRef(
185190
if (fetchDetails) {
186191
// Show loading indicator while fetching details
187192
setLoading(true);
188-
189193
// Fetch the place details - Note that placeId is already in the correct format
190194
const details = await fetchPlaceDetails(place.placeId);
191-
192195
// Merge the details with the place data
193196
const enrichedPlace = details ? { ...place, details } : place;
194-
195197
// Pass both the enriched place and session token to parent
196198
onPlaceSelect?.(enrichedPlace, sessionToken);
197199
setLoading(false);
198200
} else {
199201
// Original behavior when fetchDetails is false
200202
onPlaceSelect?.(place, sessionToken);
201203
}
202-
203204
// Generate a new token after a place is selected
204205
setSessionToken(generateSessionToken());
205206
};
206207

207-
// Show suggestions on focus if text length > minCharsToFetch
208208
const handleFocus = () => {
209+
if (skipNextFocusFetch.current) {
210+
skipNextFocusFetch.current = false;
211+
return;
212+
}
209213
if (inputText.length >= minCharsToFetch) {
210214
fetchPredictions(inputText);
211215
setShowSuggestions(true);
@@ -271,25 +275,6 @@ const GooglePlacesTextInput = forwardRef(
271275
);
272276
};
273277

274-
const renderSuggestions = () => {
275-
if (!showSuggestions || predictions.length === 0) return null;
276-
277-
return (
278-
<View style={[styles.suggestionsContainer, style.suggestionsContainer]}>
279-
<FlatList
280-
data={predictions}
281-
renderItem={renderSuggestion}
282-
keyExtractor={(item) => item.placePrediction.placeId}
283-
keyboardShouldPersistTaps="always"
284-
style={style.suggestionsList}
285-
scrollEnabled={true}
286-
bounces={false}
287-
nestedScrollEnabled={true}
288-
/>
289-
</View>
290-
);
291-
};
292-
293278
const getPadding = () => {
294279
const physicalRTL = I18nManager.isRTL;
295280
const clearButtonPadding = showClearButton ? 75 : 45;
@@ -357,6 +342,10 @@ const GooglePlacesTextInput = forwardRef(
357342
<TouchableOpacity
358343
style={[styles.clearButton, getIconPosition(12)]}
359344
onPress={() => {
345+
if (debounceTimeout.current) {
346+
clearTimeout(debounceTimeout.current);
347+
}
348+
skipNextFocusFetch.current = true;
360349
setInputText('');
361350
setPredictions([]);
362351
setShowSuggestions(false);
@@ -376,7 +365,7 @@ const GooglePlacesTextInput = forwardRef(
376365
</TouchableOpacity>
377366
)}
378367

379-
{/* Loading indicator - position adjusts based on showClearButton */}
368+
{/* Loading indicator */}
380369
{(loading || detailsLoading) && showLoadingIndicator && (
381370
<ActivityIndicator
382371
style={[styles.loadingIndicator, getIconPosition(45)]}
@@ -385,7 +374,23 @@ const GooglePlacesTextInput = forwardRef(
385374
/>
386375
)}
387376
</View>
388-
{renderSuggestions()}
377+
{/* Suggestions */}
378+
{showSuggestions && predictions.length > 0 && (
379+
<View
380+
style={[styles.suggestionsContainer, style.suggestionsContainer]}
381+
>
382+
<FlatList
383+
data={predictions}
384+
renderItem={renderSuggestion}
385+
keyExtractor={(item) => item.placePrediction.placeId}
386+
keyboardShouldPersistTaps="always"
387+
style={style.suggestionsList}
388+
scrollEnabled
389+
bounces={false}
390+
nestedScrollEnabled
391+
/>
392+
</View>
393+
)}
389394
</View>
390395
);
391396
}

0 commit comments

Comments
 (0)