Written by Abdulazeez Abdulazeez Adeshina✏️
react-query v1.0 was released on 26 February, which brought about a change in the react-query API and all-new dedicated devtools.
In this post, I will be discussing the following changes on:
- Query keys and query functions
-
useQuery
Hook - The new queries operation handler,
queryCache
- react-query-devtools
A comprehensive list of the updates (mostly minor changes) can be found on the changelog.
Moving on, I’ll be discussing these changes in the following sections but it is essential that you check this article where I talked about react-query and built a sample first.
Updating react-query
In your existing application, update your react-query package with either of these commands, depending on the package manager you’ve chosen:
npm install react-query
// or
yarn add react-query
Query keys and query functions
Query keys
The new query keys in react-query can now entertain more serializable members in the array constructor as opposed to the previous limitation of only a [String, Object]
member, giving more insight and detail to your queries.
Example:
//old
const { data } = useQuery(["recipes", { id: recipe.id }])
// new
const { data } = useQuery(["recipes", {id: recipe.id}, status])
Query functions
The query functions in the older versions of react-query accepted only one argument, which is the query object pointing to the data to be retrieved. However, the new version of react-query requires that all query key items are passed into query functions retrieving data from a source.
In the old version, the query functions were written as:
export async function fetchRecipe({ id }) {
return (await fetch(
`http://localhost:8081/${id}`
)).json();
}
But, in the new version, the above query is rewritten as:
export async function fetchRecipe(key, { id }) {
return (await fetch(
`http://localhost:8081/${id}`
)).json();
}
In the above, the key
argument there is the query name from the useQuery
Hook where this query function will be used. This new addition is very important as it enables the query function to act on a specific query where it is called from.
This is a breaking change; in newer versions, the old method of writing query functions will not work.
useQuery
Hook
In the useQuery
Hook, the paginated
optional argument has been removed due to the introduction of two new Hooks: usePaginatedQuery
and useInfiniteQuery
. This includes the following options and methods as well:
isFetchingMore
canFetchMore
fetchMore
The useQuery
Hook still maintains its mode of operation.
queryCache
import { queryCache } from "react-query";
The queryCache
instance is responsible for managing all state activities that a query undergoes in react-query. It manages all of the state, caching, lifecycle, and magic of every query. It has a number of methods, such as the prefetchQuery
, which was previously an independent Hook. The methods under the queryCache
instance are:
1. queryCache.prefetchQuery([, query], function, …)
Originally an independent Hook in react-query before the release of version 1.0.0, the queryCache.prefetchQuery()
method prefetches data and stores it in cache before the data is required by the application.
The old prefetchQuery
Hook is now discontinued and is no longer available. As such, if your application uses this Hook, you’ll have to replace prefetchQuery()
with queryCache.prefetchQuery(arg)
to avoid breaking your app upon updating the react-query package.
In older versions:
import { useQuery, prefetchQuery } from "react-query";
<Button
onClick={() => {
// Prefetch the Recipe query
prefetchQuery(["Recipe", { id: Recipe.id }], fetchRecipe);
setActiveRecipe(Recipe.id);
}}
>
In the new version:
import { useQuery, queryCache } from "react-query";
<Button
onClick={() => {
// Prefetch the Recipe query
queryCache.prefetchQuery(["Recipe", { id: Recipe.id }], fetchRecipe);
setActiveRecipe(Recipe.id);
}}
>
2. queryCache.getQueryData(querykey)
This is a synchronous method that returns the data corresponding to the query key passed into it from the cache. If the query doesn’t exist or cannot be found, undefined
is returned.
Example:
import { queryCache } from "react-query";
const data = queryCache.getQueryData("Recipes") // Returns the list of recipes present else undefined.
3. queryCache.setQueryData(querykey, updater)
This method updates a query whose identifier has been passed into the method with new data passed as the updater
value. The updater
value can either be the value to be updated or a function to update the query.
Example:
import { queryCache } from "react-query";
queryCache.setQueryData("Recipes", ["Toast Sandwich", "Brocolli"]);
queryCache.setQueryData(queryKey, oldData => newData);
setQueryData
is a synchronous method that updates the passed query immediately and creates a new query if the passed query doesn’t exist.
4. queryCache.refetchQueries(querykey)
This method refetches a single or multiple queries, depending on which is passed into it. This method is particularly useful where you want to refresh you app to get new data but do not want to reload the whole page to avoid re-rendering all the components.
Here is an example where refetchQueries
is used in an onClick
function to reload the list of recipes on a page:
import { queryCache } from "react-query";
<Button onClick={() => {
queryCache.refetchQueries("Recipes");
}}>
Refesh Recipes
</Button>
In the above code, once the button is clicked, the Recipes
query is refetched and the page updated with new recipes if the query has been updated.
5. queryCache.removeQueries(queryKeyorFn, { exact })
This method removes queries from the cache based on the query key passed into it. Queries can also be removed by passing a function instead of a query key.
Example:
import { queryCache } from "react-query";
queryCache.removeQueries("Recipes") // Removes all cached data with query key `Recipes`.
6. queryCache.getQuery(queryKey)
This method returns complete information on a query: instances, state, query identifier, and query data from the cache. This is the query method utilized in react-query-devtools, which we’ll discuss later in this post.
It tends to be unnecessary in most scenarios but comes in handy when debugging. You’d use it like this:
import { queryCache } from "react-query";
queryCache.getQuery("Recipes"); // Returns complete information about the "Recipes" query
7. queryCache.isfetching
This method returns an integer of the queries running in your application. It is also used to confirm whether there are running queries.
import { queryCache } from "react-query";
if (queryCache.isFetching) {
console.log('At least one query is fetching!')
}
Note that this isn’t a Boolean method.
8. queryCache.subscribe(callbackFn)
The subscribe
method is used to subscribe to the query cache as a whole to inform you of safe/known updates to the cache, like query states changing or queries being updated, added, or removed. This method also comes in handy when debugging.
It is used like this:
import { queryCache } from "react-query";
const callback = cache => {}
const unsubscribe = queryCache.subscribe(callback)
9. queryCache.clear()
This method clears every query presently stored in cache. This method can be used when unmounting components.
import { queryCache } from "react-query";
queryCache.clear();
This marks the end of the new queryCache
features. Let’s move on to the new react-query-devtools.
react-query-devtools
Like other devtools, react-query-devtools enables you to keep track of the query operations in your application. It can either be embedded on your app or kept afloat, giving you the option to keep it open or closed.
You can install react-query-0devtools through Yarn or npm:
npm install react-query-devtools
// or
yarn add react-query-devtools
Operations
react-query-devtools allows you to monitor the state of your queries, view data retrieved from queries, remove queries from cache and refetch queries. In the devtools console, there are four indicators of state of a running query:
- Fresh: This indicates that the query is a new one and transits into the next state almost immediately
- Fetching: This indicates that the query is being fetched from its fetcher function
- Stale: This indicates that the query has been fetched and is on standby. Queries in this state rerun when there’s a window focus on them (except when turned off from the
ReactQueryConfigProvider
) - Inactive: This indicates that the query operation has been completed
Attached below is a short clip of react-query-devtools in action, demonstrating the query operation processes:
Conclusion
The new updates to react-query are pretty excellent. The addition of the devtools makes it easy to build apps and debug with react-query.
Check here to reference the code snippets used in the new features explanations above. Keep building amazing things, and be sure to keep checking the blog for crispy new posts ❤ .
Full visibility into production React apps
Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your React apps — start monitoring for free.
The post What’s new in react-query v1.0 appeared first on LogRocket Blog.
Top comments (0)