DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Conditional Fetching - Redux-Toolkit Query (RTK Query)
Kunal Ukey
Kunal Ukey

Posted on

Conditional Fetching - Redux-Toolkit Query (RTK Query)

Introduction: RTK Query is a powerful data fetching and caching tool. It is designed to simplify common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself.

Problem: Query hooks automatically begin fetching data as soon as the component is mounted. But, there are use cases where you may want to delay fetching data until some condition becomes true.

Solution:

  • Using skip parameter in a hook
  • Using Lazy Query hook

Requirements:

  • Basic React Knowledge
  • Basic Redux-Toolkit Knowledge

Project Setup

We'll start by installing redux-toolkit & react-redux library, so open a terminal and run the command below.

npm install @reduxjs/toolkit react-redux 
Enter fullscreen mode Exit fullscreen mode

Now, Create a folder named redux inside the src folder.
Inside this redux folder, We'll create our api.js & store.js files.

api.js

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

// Generates react hooks for endpoints
export const api = createApi({
    reducerPath: "api",
    baseQuery: fetchBaseQuery({baseUrl: "https://jsonplaceholder.typicode.com/"}),
    endpoints: (builder) => ({
        getUsers: builder.query({
            query: (user) => `users/${user}`
        }),
    })
});

// Export endpoints as hooks
export const { useGetUsersQuery } = api;
Enter fullscreen mode Exit fullscreen mode

store.js

import { configureStore } from "@reduxjs/toolkit";
import { api } from "./api";

// Combines multiple states as root state
export const store = configureStore({
    reducer: {
        [api.reducerPath]: api.reducer,
    },
    // getDefaultMiddleware enables important feature like caching.
    middleware: (getDefaultMiddleware) => {
        return getDefaultMiddleware().concat(api.middleware)
    }
});
Enter fullscreen mode Exit fullscreen mode

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { Provider } from "react-redux";
import { store } from "./redux/store";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    // Wrap root component with Provider
    // Provider accepts store (root state) as prop
    <Provider store={store}> 
      <App />
    </Provider>
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

Solution 1: Using skip parameter

App.js

import { useEffect, useState } from "react";
import { useGetUsersQuery } from "./redux/api";

function App() {
  const [userData, setUserData] = useState();
  const [isUser, setIsUser] = useState(true);
  // Pass skip parameter that accepts a boolean
  const { data } = useGetUsersQuery(1, { skip: isUser });

  useEffect(() => {
    if(data) {
      setUserData([data]);
    }
    console.log(data)
  },[data])

  return (
    <div className="App"> 
      {userData && userData.map(item => (
        <div key={item.id}> 
          <p>{item.name}</p> 
          <p>{item.email}</p> 
        </div> 
      ))}
      // Triggers fetch as skip parameter is false
      <button onClick={() => setIsUser(false)}>Fetch User</button> 
    </div> 
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Solution 2: Using Lazy Query hook

For using a Lazy Query hook, we have to make a minor change to the exports inside the api.js file.

api.js

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

export const api = createApi({
    reducerPath: "api",
    baseQuery: fetchBaseQuery({baseUrl: "https://jsonplaceholder.typicode.com/"}),
    endpoints: (builder) => ({
        getUsers: builder.query({
            query: (user) => `users/${user}`
        }),
    })
});

// Add Lazy after "use" to convert it into Lazy Query hook
export const { useLazyGetUsersQuery } = api;

Enter fullscreen mode Exit fullscreen mode

App.js

import { useEffect, useState } from "react";
import { useLazyGetUsersQuery } from "./redux/api";

function App() {
  const [userData, setUserData] = useState();
  // Returns trigger function and results object
  const [getUsers, results] = useLazyGetUsersQuery();

  useEffect(() => {
    if(results && results.data) {
      setUserData([results.data]);
    }
    console.log(results)
  },[results])

  return (
    <div className="App">
      {userData && userData.map(item => (
        <div key={item.id}>
          <p>{item.name}</p>
          <p>{item.email}</p>
        </div>
      ))}
      // Fetch data on button click by envoking trigger function
      <button onClick={() => getUsers(1)}>Fetch User</button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Video Tutorial:

Thanks for reading! ❀

Top comments (0)

16 Libraries You Should Know as a React Developer

Being a modern React developer is not about knowing just React itself. To stay competitive, it is highly recommended to explore the whole ecosystem. This article contains some of the most useful React component libraries to speed up your developer workflow.