React Query - useinfinitquery,如何在获取下一页时避免组件刷新



已经使用Edamam API实现了无限滚动功能到我的食谱应用程序,但我有这个问题:

当我到达页面底部并开始获取下一页时,组件进行一次总刷新,它确实显示了每个页面之后的所有项目。

我想要的是,当我到达底部时,它开始抓取(在底部显示我的旋转器和东西)并在底部呈现下一页,而不刷新整个页面。

下面是我的代码:
const RecipesGrid = ({ query }) => {
const getRecipes = async (pageParam) => {
try {
const path = pageParam
? pageParam
: `https://api.edamam.com/api/recipes/v2?q=${query}&app_id=${process.env.REACT_APP_APP_ID}&app_key=${process.env.REACT_APP_API_KEY}&type=public`;
const response = await axios.get(path);
return response.data;
} catch (error) {
console.log(error);
}
};
useEffect(() => {
const onScroll = (event) => {
const { scrollHeight, scrollTop, clientHeight } =
event.target.scrollingElement;
if (scrollHeight - scrollTop <= clientHeight * 1.2) {
fetchNextPage();
}
};
document.addEventListener("scroll", onScroll);
return () => document.removeEventListener("scroll", onScroll);
// eslint-disable-next-line
}, []);
const {
data,
isFetching,
isFetchingNextPage,
status,
hasNextPage,
fetchNextPage,
} = useInfiniteQuery(
["recipes", query],
({ pageParam = "" }) => getRecipes(pageParam),
{
getNextPageParam: (lastPage) =>
lastPage._links.next ? lastPage._links.next.href : undefined,
}
);
if (isFetching || status === "loading") {
return <Spinner />;
}
if (status === "error") {
return <div>Whoops! something went wrong...Please, try again</div>;
}
return (
<div className={styles.Recipes}>
{data?.pages.map((item, index) => (
<React.Fragment key={index}>
{item.hits.map((recipe) => (
<Recipe recipe={recipe} key={recipe.recipe.uri} />
))}
{item.hits.length === 0 ? (
<Empty message="No results found!" />
) : null}
{!hasNextPage && item.hits.length !== 0 && (
<Empty message="No more recipes!" />
)}
</React.Fragment>
))}
{isFetchingNextPage && <Spinner />}
</div>
);
};
export default RecipesGrid;

我认为你正在卸载整个列表,因为你只在这里呈现了一个加载旋转器:

if (isFetching || status === "loading") {
return <Spinner />;
}

isFething总是为真,只要请求是在飞行中。当您获取下一页时也是如此,因此您可以进入这个早期返回并删除列表。从if语句中删除isFetching应该可以解决这个问题,因为您无论如何都可以通过

显示后台加载指示器:
{isFetchingNextPage && <Spinner />}

此外,您的错误处理将无法工作,因为您将错误转换为已解决的承诺,通过捕获它们进行日志记录而不是重新抛出它们:

} catch (error) {
console.log(error);
}

这样的事情请使用onError回调。

最新更新