如何在使用效果中设置获取限制?



在我的项目中,我试图一次获取超过 5 个 API,但是当我使用 useEffect 获取时,它会不断获取,永不停止获取。 因此,我想为此设置一个限制。

是否可以将 useEffect 限制设置为 10 次提取,然后它将自动停止获取?

这是我的代码:


const [dosa, setDosa] = useState([]);
const hola= () => {
const haspi = dv?.map((id) => {
fetch(`https://www.roads.com/roads/roadscontroll/${id}`)
.then((response) => response.json())
.then((dosa) => setDosa((prev) => [...prev, [dosa]))
.catch((error) => console.error(error))
})
return haspi ;
}

useEffect(() => {
hola();
});

在这里它不断获取,所以我想为此设置一个限制。 如何为我的代码执行此操作?任何人都可以帮助我做到这一点。 提前感谢您的帮助!

注意:出于安全原因,我在这里使用虚假API。

你可以做这样的事情:

解决方案 1:将依赖项数组添加到useEffect

const [dosa, setDosa] = useState([]);
const hola= () => {
const haspi = dv?.map((id) => {
fetch(`https://www.roads.com/roads/roadscontroll/${id}`)
.then((response) => response.json())
// To avoid confusion use different name for the received data: dosa -> newDosa
.then((newDosa) => setDosa((prev) => [...prev, [newDosa])) 
.catch((error) => console.error(error))
})
return haspi ;
}

useEffect(() => {
hola();
}, []); // Add empty dependency array here

添加空依赖项数组可防止在每次渲染时调用useEffect。这样,它仅在组件挂载上调用。

出现此问题的原因是,您在 API 成功时调用setDosa,这会导致dosa状态更新和组件重新呈现,这会导致useEffect(无依赖项)在"循环"中一遍又一遍地调用。

有关无依赖项数组和空依赖项数组之间区别的详细信息,请参阅此处:https://stackoverflow.com/a/66385496/7040601

<小时 />

解决方案 2: 下面是一个不太优雅的解决方案,它使用 ref 对象存储计数器并设置计数器的限制。

const [dosa, setDosa] = useState([]);
const counterRef = useRef(0); // Ref initialied to value = 0
const limit = 3;
const hola= () => {
const haspi = dv?.map((id) => {
fetch(`https://www.roads.com/roads/roadscontroll/${id}`)
.then((response) => response.json())
.then((newDosa) => setDosa((prev) => [...prev, [newDosa]))
.catch((error) => console.error(error))
})
return haspi ;
}

useEffect(() => {
// Only call `hola()` if counter is within the limit
if(counterRef.current < limit) 
hola();
counterRef.current++; // Increment the counter by 1
});

注意:除此之外,我同意谭@Peter在评论中的建议,您可以在上述解决方案之上应用它:

我建议使用临时数组来存储所有获取记录,并在最后设置状态,而不是在每次返回获取请求后设置状态。也许使用未更新的状态存在问题。您可以像这里一样按照答案进行操作。

出于两个原因,您不应使用useEffect运行固定次数的 API 调用。

  1. 当 API 调用未按预期工作时,您无法始终确定它们将在 10 次尝试内工作(例如,如果服务关闭)。
  2. 当它们确实起作用时,例如,在第二次尝试中,您拨打电话的剩余 8 次只是浪费宝贵的资源。

相反,您应该做的是检查 API 调用的结果,并基于此运行useEffect钩子。在您的情况下,如果 API 调用成功,将填充dosa数组。然后你的useEffect钩子变成这样:

useEffect(() => {
if (!dosa.length) {
hola(); // only runs if array is not yet populated.
}, [dosa.length]); // hook runs every time the array length changes.

最新更新