Reputation: 13
I am set up a Timeout for when the user stops typing for 3 seconds an api call is made and the ActivityIndicator appears.
edited with full code:
import React, { useState, useEffect } from 'react';
import { Text } from 'react-native';
import { ActivityIndicator } from 'react-native';
import {
Container,
SearchBar,
SearchBarInput,
SearchLoading,
SearchResultList,
Product,
} from './styles';
import api from '../../services/api';
export default function Search() {
const [searchResult, setSearchResult] = useState([]);
const [searchText, setSearchText] = useState('');
const [searching, setSearching] = useState(false);
const [focused, setFocused] = useState(false);
function renderProduct({ item }) {
return <Text>Oi</Text>;
}
let timer;
function handleChangeText(text) {
setSearching(false);
setSearchText(text);
clearTimeout(timer);
timer = setTimeout(() => setSearching(true), 3000);
}
useEffect(() => {
async function search() {
const response = await api.get(`products?search=${searchText}`);
setSearchResult(response.data);
setSearching(false);
}
if (searching) {
search();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searching]);
return (
<Container>
<SearchBar focused={focused}>
<SearchBarInput
placeholder="Pesquisar..."
onChangeText={handleChangeText}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
value={searchText}
/>
{searching && (
<SearchLoading>
<ActivityIndicator size="small" color="#000" />
</SearchLoading>
)}
</SearchBar>
<SearchResultList
data={searchResult}
keyExtractor={item => String(item.id)}
renderItem={renderProduct}
/>
</Container>
);
}
..............................................
But it's not working as it should:
https://user-images.githubusercontent.com/54718471/69919848-14680a00-1460-11ea-9047-250251e42223.gif
Upvotes: 1
Views: 942
Reputation: 6052
Remember that the body of the function is run on every single render. So the reference to the existing timer
is lost each time the component re-renders.
You can use the useRef
hook (https://reactjs.org/docs/hooks-reference.html#useref) to keep a stable reference across renders.
const timerRef = useRef(null);
function handleChangeText(text) {
setSearching(false);
setSearchText(text);
clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => setSearching(true), 3000);
}
Upvotes: 3