Reputation: 163
I have a wrapper component around a search bar that fetches suggestions with each keystroke and then searches either when a suggestion is chosen or the user hits enter/search. Upon choosing a search value, I want to persist that search item to local storage, so that I can show it on focus, much like Google. Here is a snippet of my component
export default function App() {
const [results, resultsLoading, resultsError, setParams] = useFetch();
const [suggestions, ,suggestionsError, setSuggestionsParams] = useFetch();
const [showSearchSuggestions, setShowSearchSuggestions] = useState<boolean>(true);
const [recentSearches, setRecentSearches] = useLocalStorage('recent_searches', []);
const [searchAttributes, setSearchAttributes] = useState<SearchAtrributesInterface>({
value: '',
fetchType: SEARCH_FETCH_TYPES.SUGGESTIONS
});
useEffect(() => {
const getSearchSuggestions = () => setSuggestionsParams(getAutoCompleteURL(searchAttributes.value));
const getSearchResults = () => {
setParams(getSearchURL(searchAttributes.value));
setShowSearchSuggestions(false);
};
if (searchAttributes.value) {
if (searchAttributes.fetchType === SEARCH_FETCH_TYPES.SUGGESTIONS) {
getSearchSuggestions();
} else {
getSearchResults();
setRecentSearches([searchAttributes.value, ...recentSearches])
}
}
}, [searchAttributes, setParams, setSuggestionsParams]);
return ( ... );
};
This works fine, but then I get hit with the linting warning: React Hook useEffect has missing dependencies: 'recentSearches' and 'setRecentSearches'. Either include them or remove the dependency array react-hooks/exhaustive-deps
. Upon adding those two into the dependency array, I get stuck in an infinite loop because of course recentSearches
's state is getting set, causing it to re-render and so on. I'd like to find a solution as oppose to adding // eslint-disable-next-line
because I feel there is something truly wrong that I am doing. Does anyone know what I could do differently to prevent the infinite loop and prevent the linter warning?
Upvotes: 4
Views: 1372
Reputation: 281636
There ware two things to it.
Since you wish to make use of the existing state value to update the same state you should use callback approach
setRecentSearches(prevRececentSearches => ([searchAttributes.value, ...prevRececentSearches]));
Also when you are absolutely sure that you haven't missed any dependency, you can disable the warning. Please check this post for more details: How to fix missing dependency warning when using useEffect React Hook?
Upvotes: 1