如何在重新渲染时更新 API 调用?
How can I update the API call on a re-render?
我正在自学 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
问题可能出在这里:
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
中找到更多信息
有些东西你应该看看。要防止在搜索框上输入多个 api 调用,请使用一种称为 debounce
的技术,您可以使用反应挂钩实现此目的:
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])
}
我正在自学 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
问题可能出在这里:
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
中找到更多信息有些东西你应该看看。要防止在搜索框上输入多个 api 调用,请使用一种称为 debounce
的技术,您可以使用反应挂钩实现此目的:
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])
}