From ccb26a42a3ad8d748e00cfbe9687f3198d5b8cb4 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sun, 28 Jun 2020 07:32:38 +0300
Subject: refactor: use debounce hook and add missing key

---
 src/components/Header/SearchBar.tsx | 44 +++++++++++++++----------------------
 1 file changed, 18 insertions(+), 26 deletions(-)

(limited to 'src/components/Header/SearchBar.tsx')

diff --git a/src/components/Header/SearchBar.tsx b/src/components/Header/SearchBar.tsx
index 365f33b..bff16a0 100644
--- a/src/components/Header/SearchBar.tsx
+++ b/src/components/Header/SearchBar.tsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useCallback } from 'react';
+import React, { useState, useEffect } from 'react';
 import SearchIcon from '@material-ui/icons/Search';
 import {
   InputBase,
@@ -37,41 +37,33 @@ const useStyles = makeStyles(theme => ({
 }));
 
 const SearchBar: React.FC<PropTypes> = ({ navigate }) => {
-  const [query, setQuery] = useState<string>('');
   const [results, setResults] = useState<User[]>([]);
-  const [isReady, setIsReady] = useState<boolean>(true);
-  const [shouldRefetch, setShouldRefetch] = useState<boolean>(false);
+  const [query, setQuery] = useState<string>('');
+  const [debouncedQuery, setDebouncedQuery] = useState<string>(query);
   const classes = useStyles();
 
-  const sleep = () => {
-    setIsReady(false);
-    setTimeout(() => setIsReady(true), INTERVAL);
-  };
-
-  const fetchPolls = useCallback(() => {
-    sleep();
-    get(`/users?username[$regex]=${query}&$limit=${LIMIT}`).then(response => {
-      setResults(response.data);
-    });
+  useEffect(() => {
+    const handler = setTimeout(() => setDebouncedQuery(query), INTERVAL);
+    return () => clearTimeout(handler);
   }, [query]);
 
   useEffect(() => {
-    if (isReady && shouldRefetch) {
-      fetchPolls();
-      setShouldRefetch(false);
-    }
-  }, [isReady, fetchPolls, shouldRefetch]);
-
+    const fetchPolls = () => {
+      get(`/users?username[$regex]=${debouncedQuery}&$limit=${LIMIT}`)
+        .then(response => setResults(response.data))
+        .catch(() => setResults([]));
+    };
+    if (debouncedQuery) fetchPolls();
+    else setResults([]);
+  }, [debouncedQuery]);
 
   const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
-    setQuery(event.target.value);
-    if (isReady) fetchPolls();
-    else setShouldRefetch(true);
+    setQuery(event.target.value.trim());
   };
 
   const handleClose = () => {
+    setDebouncedQuery('');
     setQuery('');
-    setResults([]);
   };
 
   const handleNavigate = (index: number) => () => {
@@ -85,12 +77,12 @@ const SearchBar: React.FC<PropTypes> = ({ navigate }) => {
         <List>
           {
           results.map((result, index) => (
-            <>
+            <div key={result._id}>
               <ListItem button onClick={handleNavigate(index)}>
                 <UserStrip user={result} navigate={navigate} />
               </ListItem>
               {(index < results.length - 1) && <Divider />}
-            </>
+            </div>
           ))
         }
         </List>
-- 
cgit v1.2.3