RTK Query: The Ultimate Data Fetching Tool for Redux π
If you are a React developer who uses Redux for state management, you probably know how tedious and repetitive it is to write data fetching and caching logic for your app. You have to use createAsyncThunk, createSlice, dispatch actions, handle loading and error states, normalize and update the data, and so on. π΄
But what if I told you that there is a better way? A way that lets you focus on the data you need, not the boilerplate code you have to write. A way that simplifies common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself. A way that is built on top of the awesome Redux Toolkit and integrates seamlessly with React. π€©
That way is called RTK Query, and it is a powerful data fetching and caching tool that is included in the Redux Toolkit package. RTK Query takes inspiration from other tools that have pioneered solutions for data fetching, like Apollo Client, React Query, Urql, and SWR, but adds a unique approach to its API design. π
In this blog post, I will show you how RTK Query works, what benefits it brings, and how to use it in your React app. Letβs get started!
What is RTK Query and how does it work? π€
RTK Query is an optional addon included in the Redux Toolkit package, and its functionality is built on top of the other APIs in Redux Toolkit. It allows you to define a set of endpoints that describe how to retrieve data from a server, how to update that data, and how to manage the cached data on the client.
RTK Query uses the concept of an API slice, which is a slice of Redux state that manages the data for a given API. You can create an API slice using the createApi function, which takes a base URL and a set of endpoints as arguments. Each endpoint can specify a query or a mutation, along with the parameters, the response type, and the transform logic.
For example, letβs say we want to create an API slice for the publicly available PokeAPI, which provides data about Pokemon. We can define our API slice like this:
// Need to use the React-specific entry point to import createApi
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import type { Pokemon } from './types'
// Define a service using a base URL and expected endpoints
export const pokemonApi = createApi({
reducerPath: 'pokemonApi',
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
endpoints: (builder) => ({
getPokemonByName: builder.query<Pokemon, string>({
query: (name) => `pokemon/${name}`,
}),
}),
})
// Export hooks for usage in functional components, which are
// auto-generated based on the defined endpoints
export const { useGetPokemonByNameQuery } = pokemonApi
As you can see, we have defined one endpoint, getPokemonByName, which is a query that takes a string as a parameter and returns a Pokemon object. We have also used the fetchBaseQuery helper function, which is a small wrapper around fetch that simplifies the requests.
RTK Query will automatically generate a Redux reducer and actions for this API slice, and store the data in a normalized cache. It will also generate React hooks that we can use to access the data in our components. For example, we can use the useGetPokemonByNameQuery hook to fetch a Pokemon by name and display its data:
import React from 'react'
import { useGetPokemonByNameQuery } from './services/pokemon'
export function Pokemon() {
// Use the predefined hook to make the query
const { data, error, isLoading } = useGetPokemonByNameQuery('bulbasaur')
return (
<div>
{error ? (
// If there is an error, show it
<div>Oh no, there was an error</div>
) : isLoading ? (
// If the request is still loading, show a spinner
<div>Loading...</div>
) : data ? (
// If we have data, show it
<div>
<img src={data.sprites.front_shiny} alt={data.name} />
<div>Name: {data.name}</div>
<div>Height: {data.height}</div>
<div>Weight: {data.weight}</div>
</div>
) : null}
</div>
)
}
Thatβs it! No need to write any reducers, actions, selectors, or even useEffects. RTK Query handles all the data fetching and caching logic for us and provides a simple and declarative way to access the data. π
What are the benefits of RTK Query? π
RTK Query is not just a convenience wrapper for Redux Toolkit. It is a powerful tool that solves many common problems and challenges that developers face when working with data fetching and caching. Here are some of the benefits that RTK Query brings:
Simplified and consistent data fetching: RTK Query abstracts away the complexities of data fetching and caching, and provides a consistent and easy-to-use API for defining and accessing data. You donβt have to worry about the request lifecycle, loading and error states, data normalization and updates, and so on. You just focus on the data you need, and let RTK Query do the rest.
Improved performance and user experience: RTK Query optimizes the performance and user experience of your app by implementing advanced features such as caching, deduplication, polling, invalidation, optimistic updates, and more. You can configure the behavior of each endpoint and control how the data is fetched and cached. RTK Query also integrates with React Query Devtools, which allows you to inspect and debug the data in your app.
Reduced boilerplate and maintenance cost: RTK Query reduces the amount of code you have to write and maintain for data fetching and caching. You donβt have to write reducers, actions, selectors, or useEffects for each API call. You donβt have to install and configure multiple libraries for different aspects of data fetching. You donβt have to keep track of the dependencies and updates of your data. You just use RTK Query and enjoy the benefits.
Seamless integration with Redux Toolkit and React: RTK Query is built on top of Redux Toolkit, and leverages its APIs like createSlice and createAsyncThunk to implement its functionality. It also generates React hooks that you can use in your components and manages the lifetime of the cached data as the components mount and unmount. RTK Query is designed to work well with Redux Toolkit and React and to enhance your existing Redux and React app.
How to get started with RTK Query? π
If you are interested in using RTK Query in your app, you can follow these steps to get started:
Install Redux Toolkit, which includes RTK Query, as a dependency in your project:
npm install @reduxjs/toolkit
Create an API slice using the createApi function, and define the endpoints that you need for your app. You can use the fetchBaseQuery helper function to simplify the requests, or use any other base query function that you prefer.
Export the generated React hooks from the API slice, and use them in your components to fetch and display the data. You can also use the other RTK Query APIs, such as useQuerySubscription, useMutation, and usePrefetch, to customize and optimize the data fetching behavior.
Enjoy the benefits of RTK Query, and explore its advanced features and configuration options.
For a more in-depth tutorial on RTK Query, you can check out the Redux Essentials tutorial on the Redux core docs site, or watch the RTK Query video course by Lenz Weber-Tronic, the creator of RTK Query, for free at Egghead.
Conclusion π
RTK Query is a powerful data fetching and caching tool that is included in the Redux Toolkit package. It simplifies common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself. It also improves the performance and user experience of your app by implementing advanced features such as caching, deduplication, polling, invalidation, optimistic updates, and more. RTK Query is built on top of Redux Toolkit and integrates seamlessly with React.
If you are a React developer who uses Redux for state management, you should definitely give RTK Query a try. It will save you a lot of time and effort, and make your app faster and more enjoyable. RTK Query is the ultimate data fetching tool for Redux, and you will love it.
Subscribe to my newsletter
Read articles from Suman Mandal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by