如果用户单击我的 React 应用程序内的按钮,则会从 API 获取一些数据。如果在 API 调用完成之前单击另一个按钮,则不应应用回调函数。不幸的是,状态(我的代码示例中的“正在加载”)在回调中没有正确的值。我做错了什么?
const [apartments, setApartments] = useState(emptyFeatureCollection);
const [loading, setLoading] = useState(true);
function getApartments() {
fetch(`https://any-api-endpoint.com`)
.then(response => response.json())
.then(data => {
if (loading) setApartments(data);
})
.catch(error => console.error(error));
}
}
useEffect(() => {
setLoading(false);
}, [apartments]);
function clickStartButton() {
setLoading(true);
getApartments();
}
function clickCancelButton() {
setLoading(false);
}
最佳答案
这里的问题是回调代码:
data => {
if (loading) setApartments(data);
}
当 loading
为 false 时,在 getApartments()
的原始闭包上下文中调用 。
这意味着回调只会看到或“继承”之前的 loading
状态,因为 setAppartments()
依赖于更新的 loading
> 状态,来自您的网络请求的数据永远不会被应用。
一个只需对代码进行最少更改的简单解决方案是将回调传递给 setLoading()
。这样做将使您能够访问当前的加载状态(即组件的状态,而不是回调中执行的闭包的状态)。这样,您就可以确定是否应该更新公寓数据:
function getApartments() {
/* Block fetch if currently loading */
if (loading) {
return;
}
/* Update loading state. Blocks future requests while this one
is in progress */
setLoading(true);
fetch(`https://any-api-endpoint.com`)
.then(response => response.json())
.then(data => {
/* Access the true current loading state via callback parameter */
setLoading(currLoading => {
/* currLoading is the true loading state of the component, ie
not that of the closure that getApartnment() was called */
if (currLoading) {
/* Set the apartments data seeing the component is in the
loading state */
setApartments(data);
}
/* Update the loading state to false */
return false;
});
})
.catch(error => {
console.error(error);
/* Reset loading state to false */
setLoading(false);
});
}
这是一个working example for you to see in action 。希望有帮助!
关于reactjs - 仅当状态为 true 时才应用获取回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57717915/