【发布时间】:2021-06-24 00:25:27
【问题描述】:
我正在尝试使用 Wikipedia API 将搜索结果分类。
这是我的Search 组件:
function Search() {
const [value, setValue] = useState("");
const [results, setResults] = useState([]);
useEffect(() => {
let timerId = null;
if (value) {
timerId = setTimeout(async () => {
const { data } = await axios.get(
"https://en.wikipedia.org/w/api.php",
{
params: {
action: "query",
list: "search",
origin: "*",
format: "json",
srsearch: value,
},
}
);
console.log(data);
setResults(data.query.search);
}, 400 );
}
return () => {
clearTimeout(timerId);
};
}, [value]);
return (
<>
<form className="ui form">
<input
type="text"
placeholder="Search Wikipedia..."
value={value}
onChange={(e) => setValue(e.target.value)}
></input>
</form>
<List results={results} />
</>
);
}
有一种增量搜索可以解释 setTimeout。
这是我的List 组件:
const List = ({ results }) => {
const [category, setCategory] = useState("");
const renderedList = results.map((item) => {
if (item.snippet.includes("film") || item.snippet.includes("movie")) {
console.log("movie", item);
}
if (
item.snippet.includes("band") ||
item.snippet.includes("musician")
) {
setCategory("music");
}
return (
<div className="ui segment">
<h2>
<a
href={"https://en.wikipedia.org?curid=" + item.pageid}
className="header"
target="_blank"
rel="noopener noreferrer"
>
{item.title}
</a>
</h2>
<p dangerouslySetInnerHTML={{ __html: item.snippet }}></p>
<p>{category}</p>
</div>
);
});
我尝试将超时设置得更高,以便在输入完整的搜索词之前没有任何活动的重新渲染,但这会得到相同的结果。 API 也只返回一个包含 10 个结果的数组,因此它不会处理大量数据。
App.js 只包含List,所以我不明白为什么会有任何问题。
任何帮助表示赞赏 - 在此先感谢!
【问题讨论】:
-
别介意我问你为什么还要从 setTimeout 调用你的 API?不确定您是出于某种实践原因还是不了解 useEffect 的目的,但基本上在 useEffect 内部,您应该像 axios.get(..).then(response => setResults(response. data)) - 不需要在钩子主体中使用 async/await(即使 async/await 很好)但是超时真的很尴尬..
-
非常不了解useEffect,我在学习react的早期阶段。我会研究你的建议。感谢您的帮助!
-
啊,好吧,所以你绝对不需要那个超时时间——因为你的状态改变会重新渲染你的组件,并且你在 axios 调用完成后设置你的状态——所以你不需要思考“程序上”但“反应性”。
-
您完全正确地认为 timout 是不必要的,再次感谢您的帮助 Ognjen。出于我的目的,我发现将结果推送到数组而不是单独类别上的 setState 就足够了。
-
不客气,我已经写了一个答案,以便将来可以帮助其他人。保重!
标签: javascript reactjs state wikipedia-api