T
TanStack•4y ago
fair-rose

How to refetch data in useInfiniteQuery() - react query?

I have a list of items and I'm using useInfiniteQuery for pagination stuff, So I have a case where I can edit Item info and then re-fetch the list again to get the updated list of items, current behavior: using queryClient.refetchQueries it replaces the prev data with the re-fetched data on the current page. await queryClient.refetchQueries(['getUsualOrders'], { stale: true, }); using refetch. it replaces the prev data with current page data without the updated data Actually, it sends a request for the next page "that doesn't exist" So how can i re-fetch the data and keep the previous data?
6 Replies
fair-rose
fair-roseOP•4y ago
code hook
export const useUsualOrders = ({lang, pageNumber = 1, token}) => {
return useInfiniteQuery(
['getUsualOrders'],
() => getUsualOrders({lang, pageNumber, token}),
{
getNextPageParam: lastPage => {
if (lastPage.next !== null) {
return lastPage.next;
}
return undefined;
},
},
);
};
export const useUsualOrders = ({lang, pageNumber = 1, token}) => {
return useInfiniteQuery(
['getUsualOrders'],
() => getUsualOrders({lang, pageNumber, token}),
{
getNextPageParam: lastPage => {
if (lastPage.next !== null) {
return lastPage.next;
}
return undefined;
},
},
);
};
UI
const [currentPageNumber, setCurrentPageNumber] = useState(1);

const {
data: usualOrdersList,
hasNextPage,
fetchNextPage,
isFetchingNextPage,
refetch: refetchUsualOrderList,
} = useUsualOrders({
lang,
token: currentUserInfo?.token,
pageNumber: currentPageNumber,
});

const loadMore = () => {
if (hasNextPage) {
setCurrentPageNumber(prev => prev + 1);
fetchNextPage();
}
};

const onRefetch = async ()=> {
// await queryClient.refetchQueries(['getUsualOrders'], {
stale: true,
});
refetchUsualOrderList({
refetchPage: (page, index) => {
return index === 0;
},
});
}

<FlatList
showsVerticalScrollIndicator={false}
data={usualOrdersList.pages.map(page => page.results).flat()}
renderItem={renderModelItems}
keyExtractor={item => item.id}
onEndReached={loadMore}
onEndReachedThreshold={0.3}
// refreshControl={
// <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
// }
style={{
backgroundColor: secondary_bg_color,
}}
contentContainerStyle={[
styles.modelList,
{
backgroundColor: secondary_bg_color,
paddingHorizontal: PADDING_HORIZONTAL.SMALL,
},
]}
ListFooterComponent={
isFetchingNextPage ? (
<ActivityIndicator color={buttonBgColor} />
) : null
}
/>
const [currentPageNumber, setCurrentPageNumber] = useState(1);

const {
data: usualOrdersList,
hasNextPage,
fetchNextPage,
isFetchingNextPage,
refetch: refetchUsualOrderList,
} = useUsualOrders({
lang,
token: currentUserInfo?.token,
pageNumber: currentPageNumber,
});

const loadMore = () => {
if (hasNextPage) {
setCurrentPageNumber(prev => prev + 1);
fetchNextPage();
}
};

const onRefetch = async ()=> {
// await queryClient.refetchQueries(['getUsualOrders'], {
stale: true,
});
refetchUsualOrderList({
refetchPage: (page, index) => {
return index === 0;
},
});
}

<FlatList
showsVerticalScrollIndicator={false}
data={usualOrdersList.pages.map(page => page.results).flat()}
renderItem={renderModelItems}
keyExtractor={item => item.id}
onEndReached={loadMore}
onEndReachedThreshold={0.3}
// refreshControl={
// <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
// }
style={{
backgroundColor: secondary_bg_color,
}}
contentContainerStyle={[
styles.modelList,
{
backgroundColor: secondary_bg_color,
paddingHorizontal: PADDING_HORIZONTAL.SMALL,
},
]}
ListFooterComponent={
isFetchingNextPage ? (
<ActivityIndicator color={buttonBgColor} />
) : null
}
/>
absent-sapphire
absent-sapphire•4y ago
You're not putting dependencies in the query key, so you're likely suffering from stale closure problems. It seems like you're mixing pagination with infinite queries. I think you just want to either manage pages in local state or use infinite queries
absent-sapphire
absent-sapphire•4y ago
Paginated / Lagged Queries | TanStack Query Docs
Rendering paginated data is a very common UI pattern and in React Query, it "just works" by including the page information in the query key: `tsx
fair-rose
fair-roseOP•4y ago
@TkDodo 🔮 I'm already using useInfiniteQuery()
export const useUsualOrders = ({lang, pageNumber = 1, token}) => {
return useInfiniteQuery(
['getUsualOrders'],
() => getUsualOrders({lang, pageNumber, token}),
{
getNextPageParam: lastPage => {
if (lastPage.next !== null) {
return lastPage.next;
}
return undefined;
},
},
);
};
export const useUsualOrders = ({lang, pageNumber = 1, token}) => {
return useInfiniteQuery(
['getUsualOrders'],
() => getUsualOrders({lang, pageNumber, token}),
{
getNextPageParam: lastPage => {
if (lastPage.next !== null) {
return lastPage.next;
}
return undefined;
},
},
);
};
should i put pageNumber in dependencies in the query key? ['getUsualOrders', pageNumber] Because when i put it, it does not work as expected it just replaces prev data with a new one when getting the next page 😅 & re-fetch does not work well
absent-sapphire
absent-sapphire•4y ago
Again, you're mixing pagination with infinite queries. Please look at the examples / docs of both and decide which approach you want to take. You will see that with infinite queries, you do not manage the "current page" manually with useState, because there is no such thing as a current page.
fair-rose
fair-roseOP•4y ago
uh yeah i misunderstand infinite queries behavior 😅 i was thinking should i pass the page number to it manually

Did you find this page helpful?