我正在尝试从我的数据库中搜索产品,并使用
lodash's debounce
在一定时间后发送请求。我面临的问题是请求仅在指定的时间之后进行,但在指定的时间间隔之后为每个字符触发请求。我只想触发一个请求,并且是针对整个单词,而不是针对每个字母。我在这里做错了什么?另外,我愿意对此代码进行任何优化(如果有的话):)
SearchBar.js
function SearchBar() {
const [searchText, setSearchText] = useState("");
const searchResultsRef = useRef(null);
const dispatch = useDispatch()
const sendRequest = (searchText) => {
dispatch(getSearchedCategories(searchText))
};
const debouncedSendRequest = debounce(sendRequest, 5000);
const handleInputChange = (event) => {
const inputValue = event.target.value.toLowerCase();
if (inputValue === "") {
setSearchText("");
} else {
setSearchText(inputValue);
if(inputValue.trim().length > 2) {
debouncedSendRequest(inputValue.trim())
setShowSearchResult(true)
}
}
};
const hideSearchResults = () => {
setShowSearchResult(false);
}
useEffect(() => {
const handleClickOutside = (event) => {
if (searchResultsRef.current && !searchResultsRef.current.contains(event.target)) {
hideSearchResults();
}
};
// add event listener to detect clicks outside of the search component
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [searchResultsRef]);
return (
<div className="searchContainer">
<div className="searchInputs">
<input
type="search"
placeholder="Search for a product"
value={searchText}
onChange={handleInputChange}
/>
...
</div>
...
</div>
);
}
action.js
export const getSearchItem = (searchedItem) => async (dispatch) => {
try {
...
const { data } = axios.get(// my api)
...
} catch(error) {
...
}
}
const debouncedSendRequest = debounce(sendRequest, 5000);
每次组件渲染时,这一行都会创建一个全新的
debouncedSendRequest
函数。它有自己的内部计时器,与您上次创建它的时间无关。为了使去抖动发挥作用,您必须仅创建该函数一次。您可以使用 useMemo
来做到这一点:
const debouncedSendRequest = useMemo(() => {
const sendRequest = (searchText) => {
dispatch(getSearchedCategories(searchText))
};
return debounce(sendRequest, 5000);
}, [dispatch]);