QueryClientProvider
QueryClientProvider widget
The first thing needed for storing any form of data is a store. QueryClientProvider is basically a InheritedWidget which wraps around the actual store QueryClient. You must use wrap your MaterialApp or CupertinoApp with QueryClientProvider for using same QueryClient across all screens/routes. Or, if you want you can use QueryClientProvider anywhere in the Widget Tree to a different QueryClient to the descendant widgets
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return QueryClientProvider(
child: MaterialApp(
title: 'Fl-Query Example',
home: const MyHomePage(),
),
);
}
}
QueryClientProvider has many properties that can be configured. You can configure refetch behaviors, staleDuration, retries etc
Here I'm increasing the staleTime to 10 seconds. This means that if the data is outdated after 10 seconds, it will be refetched in the background smartly when needed. The default value is 2 minutes 250 milliseconds
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return QueryClientProvider(
child: MaterialApp(
title: 'Fl-Query Example',
home: const MyHomePage(),
),
);
}
}
If you provide
QueryClienttoQueryClientProviderthen assign all the parameters toQueryClientitself
For more information on how to use QueryClientProvider, please refer to the QueryClientProvider API Reference
QueryClient
The QueryClient is the store that holds all the query/mutation data. You can create a new instances of QueryClient by calling QueryClient() constructor. But it is recommended to use QueryClientProvider to create a new instance of QueryClient and use it across the app.
QueryClient can be accessed from anywhere in the widget tree using QueryClient.of(context). It can be useful for imperative data manipulation
Often there are cases where imperative access to the API is necessary. e.g. invalidating/refreshing a query from another page after a mutation
QueryClient gives access to the base of this framework. SO BE CAREFUL WHILE USING IT
final queryClient = QueryClient.of(context);
You can create/pre-fetch a query like this:
await queryClient.fetchQuery(
'todos',
() => api.getTodos(),
);
queryClient.fetchQuerywill create and fetch a query immediately if it's not already available. To just create a query and not fetch it, usequeryClient.createQueryinstead
Also, you can refresh queries or queries that start with a certain prefix:
// Refresh a single query
await queryClient.refreshQuery(
'todos',
exact: true // pass false if you want to refresh a query with prefix
);
// Refresh multiple queries passing multiple keys
await queryClient.refreshQueries(['todos', 'posts']);
// Refresh queries with prefix
await queryClient.refreshQueriesWithPrefix('todo/');
You can also use QueryClient to create, get, refresh/mutate InfiniteQuery(s) & Mutation(s)
QueryCache
Uhm, actually we kinda lied. QueryClient technically holds all the data but truly QueryCache is the one
that truly holds all the query and mutations. QueryClient is just a wrapper around QueryCache that provides some
useful methods and properties. QueryCache can be accessed using QueryClient's cache property but it doesn't have any
useful methods or properties. So, it is recommended to use QueryClient instead of directly accessing the QueryCache
Also while using QueryClient you don't need to worry about QueryCache at all. It is just for the sake of knowledge
Deleting queries/mutations from cache
One thing noticeable is there's no way to delete query/mutation using QueryClient. You have to use QueryCache for
that part. It is the only reason ever to use QueryCache
Accessing the QueryCache directly is not recommended. And altering the cache can lead to unexpected behavior and
potential crashes
Here's how to delete a query/mutation from cache:
final queryClient = QueryClient.of(context);
final query = queryClient.getQuery('todos');
final mutation = queryClient.getMutation('add-todos');
queryClient.cache.removeQuery(query);
queryClient.cache.removeMutation(mutation);
Deleting a query/mutation from cache can be dangerous as it can cause memory leaks, infinite re-renders and crash if the
Query, InfiniteQuery or Mutation is still in use and mounted