-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
It looks like the entire lifecycle of onQueryStarted occurs when fetchNextPage is called.
However, often fetchNextPage is expected to often indicate end-of-list.
This seems like unexpected behavior, because no additional base-query usage is made, but any side effects of onQueryStarted DO occur.
Take the following example, with the code below.
In this example, patchCachedUser syncs some metadata between the query-notifications endpoints with the get-user endpoint (the total notifications count, to prevent flickering while states reconcile).
The behavior that occurs is:
- Hook mounts with page of data.
onQueryStarteddoes not fire unless this is the first time the hook is mounted, as expected. - The end of list is reached, triggering
fetchNextPage. fetchNextPage, viagetNextPageParam, knows we're at the end-of-list, returning undefined.onQueryStartedis fired, ALWAYS. however,queryFulfilledis already resolved, and so it does the remaining work (e.g. pessimistic updates), using the old data.
getNotifications: build.infiniteQuery<
{
notifications: Notification[];
user: Pick<User, "numUnreadNotifications">
},
{
uid: string;
limit: number;
filter: "read" | "unread"
},
PaginationCursor | undefined
>({
onQueryStarted: async (args, { dispatch, queryFulfilled }) => {
try {
console.log("Fetching notifications for user:"); // THIS logs during a `fetchNextPage` call
const { data } = await queryFulfilled; // Base query has its own logging -- this is already resolved during the calls.
const lastPage = data.pages[data.pages.length - 1];
const user = lastPage.user;
dispatch(patchCachedUser(args, user)); // This now badly assumes that the data is the most-recent from the API, but its from a previous cached call.
} catch (error) {
void error;
}
},
infiniteQueryOptions: {
initialPageParam: undefined,
getNextPageParam: ({
notifications: lastPage,
}): undefined | PaginationCursor => {
const lastItem = lastPage?.at(-1);
return lastItem && { createdAt: lastItem.createdAt };
},
},This looks like unexpected behavior to me, and I don't see a clean way to get around this (to prevent side affects from occuring multiple times from the same resolved underlying queryFulfilled)