【发布时间】:2021-09-21 07:56:09
【问题描述】:
我有一个主页,其中显示来自searchContext 的搜索结果。这是我的home page 代码。
import { useSearch } from "./SearchContext";
const Home = () => {
const { isLoading, search, searchResult } = useSearch();
const startIndex = Math.floor(Math.random() * searchResult.length - 5);
return (
<>
<h3>Home page</h3>
{isLoading ? (
<h1>LOADING...</h1>
) : (
<div>
<div>Search value: {search}</div>
{searchResult.slice(startIndex, startIndex + 5).map((el) => (
<li key={el.id}>{el.title}</li>
))}
</div>
)}
</>
);
};
export default Home;
这是我的searchContext。
import { createContext, useEffect, useContext, useState } from "react";
export const SearchContext = createContext({
isLoading: false,
search: "",
searchResult: [],
setSearch: () => {}
});
export const useSearch = () => useContext(SearchContext);
const SearchProvider = ({ children }) => {
const [search, setSearch] = useState("");
const [items, setItems] = useState([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const searchNews = async () => {
console.log(search);
setIsLoading(true);
const news = await fetchNews(search, 15, 1);
setItems(news);
setIsLoading(false);
};
const fetchNews = async (section, pageSize, page) => {
// const url = `${baseUrl}${section}?page-size=${pageSize}&page=${page}&api-key=${apiKey}`;
const url = "https://jsonplaceholder.typicode.com/posts";
const news = await fetch(url);
return await news.json();
};
if (search.length > 0) { // I added this condition so that searchNews is not called when search is empty.
searchNews();
} // Here I can add an else statement and call `setItems([])` to set empty array to items but it does not work either.
}, [search]);
return (
<SearchContext.Provider
value={{
isLoading,
search,
searchResult: items,
setSearch: (e) => setSearch(e.target.value)
}}
>
{children}
</SearchContext.Provider>
);
};
export default SearchProvider;
当我向input field 输入文本时,此上下文一直在调用searchNews。这适用于搜索和显示结果。但是,当我从 input field 中删除 search string 时,我不希望它显示或检索更多 API 调用的结果。现在,如果我从input field 中慢慢删除search string,这将起作用。但是当我越来越快地删除search string 时,items 仍然有结果,它会在home page 上显示这些结果。我不想要这个。我想当search input 为空时,我不想在home page 或任何页面上显示任何search result。
为了解决这个问题,我在 searchContext 中添加了一个 if 条件,它检查 search 是否不为空,这意味着 input field 不为空,然后调用 searchNews 方法并从 API 加载结果,但如果它为空然后不要再调用searchNews,它不应该在任何页面上显示search result。
这是带有搜索输入字段的 search.js 页面。
import { useSearch } from "./SearchContext";
const Search = () => {
const { setSearch } = useSearch();
return (
<>
<input
type="text"
name="search"
placeholder="Enter search term"
onChange={setSearch}
/>
</>
);
};
export default Search;
当我越来越快地删除搜索字符串时,如何解决这个问题?
这里是这个问题的代码沙箱。
【问题讨论】:
-
使用 Debounce 怎么样? codesandbox.io/s/…
-
@PsyGik 我检查了你的沙箱,它仍在使用 debounce 显示结果。
-
@Om3ga 请查看我的更新答案。我想这就是你想要的
-
我不明白。
fetchNews(search.length ? search : "news", 15, 1);告诉如果不存在搜索术语,则使用默认术语即news获取。但您也不想显示默认搜索结果? -
不应该有这种情况。基本上应该是
fetchNews(search, 15, 1);。我更新了沙盒。
标签: javascript reactjs react-context