Conditional Fetching - Redux-Toolkit Query (RTK Query)

kunalukey

Kunal Ukey

Posted on November 16, 2022

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! ❤

💖 💪 🙅 🚩
kunalukey
Kunal Ukey

Posted on November 16, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related