-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
The changes to allow awaiting query.refetch()
are really nice, as is the ability now to build paginated flows with merge
/ forceRefetch
/ serializeQueryArgs
.
Is there a way that promsie-based refetch could work with forceRefetch
?
For context, I'm using a pattern very similar to #2874 where pagination cursor indicates a full-refresh from the head of the list.
Here's a basic example, where an endpoint would take an item as a cursor for the next page, or no cursor for the head:
// api
...
getList: builder.query<
{
items: Item[];
args: {
cursor?: Item;
};
},
{
cursor?: Item;
}
>({
query: ({ cursor }) => ({
endpoint: "itemList",
payload: {
cursor,
},
}),
transformResponse: (items: Item[], meta, args) => ({
items,
args,
}),
serializeQueryArgs: ({ endpointName }) => {
return endpointName;
},
merge: (currentCache, responseData) => {
if (responseData.args.cursor) {
currentCache.items.push(...responseData.items);
currentCache.args = responseData.args;
} else {
return responseData;
}
},
}),
// component
const ListComponent = () => {
const [cursor, setCursor] = useState<Item>();
const query = useGetListQuery({ cursor });
const loadMore = () => setCursor(query.data?.items[query.data?.items.length - 1]);
const refreshList = () => setCursor(undefined);
return (
<List
isRefreshing = { /* THIS IS THE ISSUE */ }
data={ query.data?.items ?? [] }
onEndReached={ loadMore }
onRefresh={ refreshList }
...
/>
)
};
With a normal query, this is now easily achievable via something like:
const Component = () => {
const query = useQuery();
const [isRefreshing, setIsRefreshing] = useState(false);
const refresh = async () => {
setIsRefreshing(true);
await query.refetch();
setIsRreshing(false);
};
return <Foo data={query.data} onRefresh={refresh} isRefreshing={isRefreshing} />
}
But since the refresh is triggered by the param change, it feels like it's back to needing a solution like pre-promise-refetch ( like tracking isFetching
and trying to ensure the cause of the fetching is known)
...
Conceptually, what I want is trigger a refetch and await it in a single step:
refreshList = async () => {
setIsRefreshing(true);
setCursor(undefined);
await query.refetch();
setIsRefreshing(false);
}