我正在教自己React Hooks,我想在用户输入搜索框时更新API调用。实时搜索的排序。我已经收集到该事件仅在页面加载时触发,但我该如何解决?
样品在这里:https://codesandbox.io/s/6x1xp57zmk
import React, {useState, useEffect} from 'react';
function App() {
const [cardNames, setCardName] = useState([])
const rezCards = async () => {
//const rez = await fetch('https://api.scryfall.com/cards?page=3')
const rez = await fetch ('https://api.scryfall.com/catalog/card-names')
const json = await rez.json()
setCardName(json.data)
}
useEffect(() => {
rezCards()
},[])
return <ul>{cardNames
.slice(0,50)
.map(
(cardName) => {
return <li key={cardName}>{cardName}</li>
}
)}</ul>
}
export default App
你应该看看有什么东西。为了防止在搜索框上输入多个api调用,使用一种名为debounce
的技术,您可以使用react钩子实现此目的:
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(
() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
},
[value, delay],
);
return debouncedValue;
}
function App() {
const debouncedInput = useDebounce(searchInputValue, 300);
useEffect(() => {
rezCards()
},[debouncedInput])
}
问题可能出在这里:
useEffect(() => {
rezCards()
},[])
您已将第二个参数保留为空数组,这导致useEffect
仅在组件装载时运行一次,与componentDidMount
相同。
如果您希望在更改状态时触发useEffect
,则可以添加状态作为挂钩的依赖项,例如
const { callThisEffectWhenThisValueIsChanged, changeValue } = useState('');
useEffect(() => {
// Do anything with here, for eg call APIs
},[callThisEffectWhenThisValueIsChanged])
changeValue(newValue);
因此,在CodeSandbox代码中,您需要做的就是在依赖项中添加searchInput
,每当搜索输入发生更改时,它都会再次调用钩子。
useEffect(() => {
rezCards();
}, [searchInput]);
永远记住,只要你的效果使用任何状态,你需要添加状态作为效果钩子的依赖
您可以在React Hook doc中找到更多信息