React is a popular JavaScript library for building user interfaces for web applications. When building an application, it's important to consider an efficient data management approach to ensure you fetch and render data in the browser appropriately, in response to user interactions.

However, managing this process can seemingly become a tedious and error-prone task especially if you are fetching data from multiple sources, and you need to consistently update a number of states. In such cases, Redux Toolkit Query provides an efficient solution.

What Is Redux Toolkit Query?

Redux Toolkit Query (RTK Query) is a data-fetching tool built on top of the Redux Toolkit. Its official documentation describes RTK Query as "a powerful data fetching and caching tool designed to simplify common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself".

Essentially, it provides a set of features and capabilities that streamline the process of fetching and managing data from APIs or any other data source from a React application.

A MacBook with lines of code on its screen on a busy desk

While there are similarities between Redux Toolkit Query and React Query, one main advantage of Redux Toolkit Query is its seamless integration with Redux, a state management library, allowing for a complete data fetching and state management solution for React applications when used together.

Some of the core features of RTK include data caching, a query management feature, and error handling.

Getting Started With Redux Toolkit Query in a React Application

To get started, you can quickly spin up a React project locally using the Create React App command.

        mkdir React-RTQ
cd React-RTQ
npx create-react-app react-rtq-example
cd react-rtq-example
npm start

Alternatively, you can set up a React project using Vite, a new build tool and development server for web applications.

You can find this project's code in this GitHub repository.

Install the Required Dependencies

Once you have your React project up and running, go ahead and install the following packages.

        npm install @reduxjs/toolkit react-redux
    

Define an API Slice

An API slice is a component that includes the necessary Redux logic for integrating with and interacting with specified API endpoints. It provides a standardized way to define both query endpoints for fetching data and mutation endpoints for modifying the data.

Essentially, an API slice allows you to define the endpoints for requesting and making changes to the data from a particular source, providing a streamlined approach to integrating with APIs.

In the src directory, create a new folder and name it, features. Inside this folder, create a new file: apiSlice.js, and add the code below:

        import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

export const productsApi = createApi({
  reducerPath: "productsAp",
  baseQuery: fetchBaseQuery({ baseUrl: "https://dummyjson.com/" }),

  endpoints: (builder) => ({
    getAllProducts: builder.query({
      query: () => "products",
    }),
    getProduct: builder.query({
      query: (product) => `products/search?q=${product}`,
    }),
  }),
});

export const { useGetAllProductsQuery , useGetProductQuery } = productsApi;

This code defines an API slice called productsApi using Redux Toolkit's createApi function. The API slice takes in the following properties:

  • A reducerPath property - sets the name of the reducer in the Redux store.
  • The baseQuery property - specifies the base URL for all API requests using the fetchBaseQuery function provided by Redux Toolkit.
  • API endpoints - specify the available endpoints for this API slice using the builder object. In this case, the code defines two endpoints.

Finally, two hooks are generated from the productsAPI object which identifies the two endpoints. You can use these hooks in various React components to make API requests, retrieve data, and change the state in response to the user's interaction.

This approach streamlines the state management and data fetching in the React application.

Configure the Redux Store

After fetching the data from the API, RTK Query caches the data in the Redux store. The store, in this case, serves as a central hub for managing the state of API requests made from the React application, including the data retrieved from those API requests ensuring components access and update this data as needed.

In the src directory, create a store.js file and add the following lines of code:

        import { configureStore } from "@reduxjs/toolkit";
import { productsApi } from "./features/apiSlice";

export const store = configureStore({
  reducer: {
   [productsApi.reducerPath]: productsApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
   getDefaultMiddleware().concat(productsApi.middleware),
});

This code creates a new Redux store, with two main pieces of configuration:

  1. Reducer: This defines how the store should handle updates to the state. In this case, the productsApi.reducer is passed in as the reducer function and is given a unique reducerPath key to identify it within the store's overall state.
  2. Middleware: This defines any additional middleware that should apply to the store.

The resulting store object is a fully-configured Redux store, which can be used to manage the state of the application.

By configuring the store in this way, the application can easily manage the state of API requests, and process their results in a standardized way using the Redux Toolkit.

Create a Component to Implement the RTK Functionality

In the src directory, create a new components folder with a new file inside: Data.js.

Add this code to the Data.js file:

        import { useGetAllProductsQuery } from "../features/apiSlice";
import React, { useState } from "react";
import "./product.component.css";

export const Data = () => {
  const { data, error, isLoading, refetch } = useGetAllProductsQuery();
  const [productsData, setProductsData] = useState([]);

  const handleDisplayData = () => {
    refetch();
    setProductsData(data?.products);
  };

  return (
    <div className="product-container">
      <button className="product-button" onClick={handleDisplayData}>
        Display Data
      </button>
      {isLoading && <div>Loading...</div>}
      {error && <div>Error: {error.message}</div>}
      <label className="product-label">Products:</label>
      {productsData && productsData.length > 0 && (
        <ul>
          {productsData.slice(0, 4).map((product) => (
            <li className="product-details" key={product.id}>
              <p>Name: {product.title}</p>
              <p>Description: {product.description}</p>
              <p>Price: {product.price}</p>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

This code demonstrates a React component that uses the useGetAllProductsQuery hook provided by the API slice to retrieve data from the specified API endpoint.

When the user clicks the Display Data button, the handleDisplayData function executes, sending an HTTP request to the API to retrieve product data. Once the response is received, the products' data variable is updated with the response data. Finally, the component renders a list of product details.

Update the App Component

Make the following changes to the code in the App.js file:

        import "./App.css";
import { Data } from "./components/Data";
import { store } from "./store";
import { Provider } from "react-redux";
import { ApiProvider } from "@reduxjs/toolkit/query/react";
import { productsApi } from "./features/apiSlice";

function App() {
  return (
    <Provider store={store}>
      <ApiProvider api={productsApi}>
        <div className="App">
          <Data />
        </div>
      </ApiProvider>
    </Provider>
  );
}

export default App;

This code wraps the Data component with two providers. These two providers grant the component access to the Redux store and RTK Query features allowing it to fetch and display data from the API.

Using Redux Toolkit Query in Web Applications

It’s easy to configure Redux Toolkit Query to efficiently retrieve data from a specified source with minimal code. Moreover, you can also incorporate functions to modify stored data by defining mutation endpoints in the API slice component.

By combining the features of Redux with RTK's data-fetching abilities, you can obtain a comprehensive state management solution for your React web applications.