In 8.1 and 8.2 we added two new controller methods, along with some improvements to edge cases for Collections
- Controller.expireAll() - refresh data while continuing to show stale data
- Controller.fetchIfStale() - fetch data only if it is marked as expired
- Collections filtering support FormData arguments.
Controller.expireAll
Similar to use case of invalidateAll(), but does not result in loading condition.
controller.expireAll() sets all responses' expiry status matching testKey
to Stale.
This is sometimes useful to trigger refresh of only data presently shown when there are many parameterizations in cache.
import { type Controller, useController } from '@data-client/react';
const createTradeHandler = (ctrl: Controller) => async trade => {
await ctrl.fetch(TradeResource.getList.push({ user: user.id }, trade));
ctrl.expireAll(AccountResource.get);
ctrl.expireAll(AccountResource.getList);
};
function CreateTrade({ id }: { id: string }) {
const handleTrade = createTradeHandler(useController());
return (
<Form onSubmit={handleTrade}>
<FormField name="ticker" />
<FormField name="amount" type="number" />
<FormField name="price" type="number" />
</Form>
);
}
Controller.fetchIfStale
controller.fetchIfStale() fetches only if endpoint is considered 'stale'.
This can be useful when prefetching data, as it avoids overfetching fresh data.
An example with a fetch-as-you-render router:
{
name: 'IssueList',
component: lazyPage('IssuesPage'),
title: 'issue list',
resolveData: async (
controller: Controller,
{ owner, repo }: { owner: string; repo: string },
searchParams: URLSearchParams,
) => {
const q = searchParams?.get('q') || 'is:issue is:open';
await controller.fetchIfStale(IssueResource.search, {
owner,
repo,
q,
});
},
},
Stale
Date.now() <= expiresAt && expiryStatus !== ExpiryStatus.Invalid
Collections and FormData
Collections can filter based on FormData arguments
ctrl.fetch(
getPosts.push,
{ group: 'react' },
new FormData(e.currentTarget),
);
Say our FormData contained an author
field. Now that newly created
item will be properly added to the collection list for that author.
useSuspense(getPosts, {
group: 'react',
author: 'bob',
});
In this case if FormData.get('author') === 'bob'
, it will show
up in that useSuspense() call.
See more in the Collection nonFilterArgumentKeys example