Introduction to Redux Toolkit Query with TypeScript

React

The Redux team is working hard to create tools that are helpful in many real-life situations. For example, Redux Toolkit is a big step in simplifying how we write applications with Redux. Another helpful tool is the Redux Toolkit Query. Its primary sources of inspiration are the Apollo Client and React Query.

The code we usually write for fetching data is often very repetitive. RTK Query aims to do a lot of the work and make our code more consistent and concise. It comes with loading state handling and even cache management. On top of that, RTK Query generates React hooks ready to use. It offers excellent support for TypeScript because it is written in it.

In this article, we go through all the basic features of RTK Query while using TypeScript.

Here we use an official Redux Toolkit template with TypeScript. To get it, run .

Defining the basics of our API

To start using the RTK Query, we need to use the function.

A few important things are happening above. First, we need to define the property to tell the Redux Toolkit where we want to keep all of the data from the API in our store.

We also need to tell the RTK how to make our API requests by providing the parameter. A common way is using the function, a wrapper around the native Fetch API. Even though the above is the solution suggested by the official documentation, RTK aims not to enforce it. So, for example, we can write our base query function that uses axios.

In the property called , we specify a set of operations we want to perform with the API. We do that by using the object. When we aim to retrieve the data, we should use the function. When we want to alter the data on the server, we need to call the method.

Both and uses generic types. For example, in the is the type of data in the response. When getting the photo, the is the type of argument we want the user to pass. Since the query does not require any arguments, we must explicitly pass .

Defining the endpoints causes the React Toolkit to generate a set of hooks to interact with our API. We need to use TypeScript in version 4.1 or greater for the hooks to work correctly.

In our code snippet, we use the environment variable. Therefore, we need to add it to our file for the url to be available.

.env

Attaching the RTK Query to the store

The function creates a reducer and a middleware we need to attach to our existing Redux store.

If you want to know more about Redux Middleware, check out Redux middleware and how to use it with WebSockets

Above, the is a thing worth noting. We can set the or the flags to true when using a query. They tell RTK Query to refetch the data when the application window regains focus, or the network connection is reestablished. For it to work, we need to listen to events such as:

When we look under the hood, we can see that the function attaches callbacks to the above events. So as long as you don’t use the mentioned flags, you don’t need to use .

Querying the data

The essential auto-generated hook related to queries is the . Using it automatically fetches the data.

The cache behavior

It is essential to understand that if we render the multiple times with the same , the hook returns the result from the cache. The above happens as long as 60 seconds didn’t yet pass until the last component stopped using the hook with a given id.

60 seconds can be changed to another value using the property.

We can alter this behavior in a few ways. For example, we can use the property to allow the query to refresh automatically.

Above I’m using a numeric separator to make the number more readable.

We can also use the flag to skip the cached result.

Instead of we can also pass a number of seconds. In this case RTK refetches if enough time has passed.

RTK also gives us a way to manually request the latest data with the refetch function.

We can also use the and flags as mentioned before in this article.

Updating the data with mutations

To update the data, we need to use mutations. To do that, we can use the most significant hook used for mutation, the hook.

The crucial thing is that mutating a post with a given id should modify the cache. One way to achieve that is with tags.

Automated cache invalidating with tags

RTK query creates a tag system to automatically refetch the data affected by mutations. Queries can provide tags, while mutations can invalidate them.

In our example above, we can see that the provides just one tag: .

The query provides one tag per photo. For example, using causes the tag to be created.

The mutation would invalidate two tags if the update were successful.

Using the above mutation invalidates the following tags:

Because of that, running the above mutation causes three API requests:

  • ,
  • ,
  • .

Thanks to doing the above, the cache is refreshed for the and the query.

Manual cache invalidating

Making additional API requests every time we change a single photo is not optimal. In RESTful APIs, PATCH and PUT requests often return the modified entity. We can use that to perform manual cache invalidation. To do that, we need to define an function.

One way of doing the above is to perform an optimistic update. We assume that our API request will probably be successful, and we want to make the changes immediately. However, if our API request fails for some reason, we undo our changes.

The second approach we can implement is the pessimistic update. Here, we wait for the request to be completed before modifying the cache.

Splitting the code

When using React Toolkit Query, we are expected to use the function just once. However, when our application uses a lot of different endpoints, defining them in one place can lead to a messy codebase. Fortunately, with RTK, we can split our endpoints into multiple additional files.

Please notice that we’re still defining the array in the main API definition. An alternative to doing that is to use the function.

Summary

We’ve gone through all of the features we need to start using React Toolkit Query in this article. This included defining the API with code splitting, performing queries, and altering the cache with mutations. RTK Query proves to be a great tool that we can use for data fetching and caching. We can even use the Redux DevTools extension to view our cached data through the developer tools. It does a lot of the job for us and makes a lot of sense especially if we already use Redux in our application.

Subscribe
Notify of
guest
4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Lenz Weber
Lenz Weber
2 years ago

Great article!
One nitpick:

is doing a bit much. You can either use Object.assign to update an existing object or create and assign a new object, both is not necessary. It behaves like an immer reducer here.
So either

or

Victor Olaoye
Victor Olaoye
2 years ago

When I tried to use the query hook in a component, it returns an error. In my case the data is an object so the error is ‘Object is of type unknown’

Neil
Neil
1 year ago

Please share what the Photo type is please – import Photo from ‘./photo’;

Ben
Ben
10 months ago

This is a fantastic introduction that cleared up a lot of my initial confusion with using RTK Query. Thank you for taking the time to write and share this!