DEV Community

Cover image for How to use RTK query in Redux toolkit
Ifeanyi Chima
Ifeanyi Chima

Posted on • Updated on

How to use RTK query in Redux toolkit

Redux toolkit query or RTK query is the greatest human invention since the wheel. It simplifies performing asynchronous tasks such as fetching data from an API. In this article, I will show you how I use it and enjoy the full benefits.

Check out my tutorial on setting up rtk query

BMC logo

Globally transform Response

I was working on a project one day and I wanted to be able to (globally) define a transformResponse for all queries endpoint.
After my research I came up with a solution.

In your API slice, you can change the response for all the endpoints. To do this, you wrap your baseQuery with a custom function that does these transformations. reference

const baseQueryWithChange = async (args, api, extraOptions) => {
    let result = await baseQuery(args, api, extraOptions);
    if (result.data) {
        result.data = result.data.data
    }
    return result
}
Enter fullscreen mode Exit fullscreen mode

wrap baseQuery with the baseQueryWithChange function

export const apiSlice = createApi({
    baseQuery: baseQueryWithChange,
    endpoints: builder => ({})
})
Enter fullscreen mode Exit fullscreen mode

transformResponse for each endpoint

This one is easy, for each endpoint you inject to your API slice, you can transform the response of the API call.

import { apiSlice } from "../../app/api/apiSlice";

export const extendedApiSlice = apiSlice.injectEndpoints({
    endpoints: builder => ({
        getHistory: builder.query({
            query: credentials => ({
                url: `/history/${credentials.id}`,
                method: "GET"
            }),
            providesTags: ["History"],
            transformResponse: (response) => response.result,
        })
    })
})


export const {
    useGetHistoryQuery
} = extendedApiSlice

Enter fullscreen mode Exit fullscreen mode

refetch();

refetch: A function returned by the query hooks. Triggers a refetch (usually to be called inside useEffect).

With this function, I can make an API call every ten seconds. reference

// stocks component


import { useGetStocksQuery } from '../features/stocksList/stocksListApiSlice';
import { useEffect, useRef } from "react";

const Stocks = () => {

    const tickerArray = [
        "AAPL",
        "TSLA",
        "NKE",
        "MSFT",
        "AMZN",
        "PLTR",
        "BYND",
        "GOOGL",
        "META",
        "SNAP",
        "NFLX"
    ];


    // store the timer inside useRef hook to ensure persistentence
    const stockTimerId = useRef();


   let {
        data: list,
        refetch
    } = useGetStocksQuery({tickerArray});


    useEffect(() => {

   stockTimerId.current = await setInterval(() => refetch(), 10000);

  }
        // when component unmounts clear the interval
        return () => clearInterval(stockTimerId.current)
    })


return (
  <>Your JSX goes here</>
)

}

export default Stocks

Enter fullscreen mode Exit fullscreen mode

Query params RTK query

How to query with multiple query parameters?

If I want to make my URL to look like this https://api.coingecko.com/api/v3/coins/markets?vs_currency=ngn&order=market_cap_desc&per_page=100&page=1&sparkline=false

baseURL: https://api.coingecko.com/api/v3/coins/markets

Query Parameters: ?vs_currency=ngn&order=market_cap_desc&per_page=100

We can achieve this in RTK query, by creating an object that contains all the query paramters, and passing it as an option into the hook.


const queryParams = {
  vs_currency: "usd",
  order: "market_cap_desc",
  page: "1",
  sparkline: "false",
  ids: debouncedSearchQuery,
  price_change_percentage: "1"
}

const { data: coinSearchResult, isSuccess: searchedForCoin } = useGetCoinQuery(queryParams)

// apiSlice

getCoins: builder.query({
  query: (arg) => ({
    url: `/coins/markets`,
    params: {...arg}
  }),
})

Enter fullscreen mode Exit fullscreen mode

Stackoverflow question: RTK Query query parameter

Second question: Redux Toolkit RTK Query sending query parameters

Path params RTK query

How to query with multiple path parameters?

If I want to make my URL look like this https://api.coingecko.com/api/v3/coins/bitcoin

baseURL: https://api.coingecko.com/api/v3/coins

Path Params: /bitcoin/usd

query accepts only one argument, you use an object that contains all your path parameters when using the automatically generated hooks.


   // apiSlice

    getReport: builder.query({
      query: ({bitcoin, currency}) =>
        `/${bitcoin}/${currency}`,
    }),

    useGetReportQuery({
      bitcoin,
      currency
    });
Enter fullscreen mode Exit fullscreen mode

GitHub issue: How to query with multiple path parameters

Option: skip in RTK query

I want to search through an array based on an input field provided in the app.

I have a useSearchMovieQuery in RTK Query API which search for whatever a user enters in the search field. I want to prevent the query from running on the initial render, which can be achieved by skipping the query using "skip" or "skipToken".

I want only to run this query after the user stops typing, not immediately after onChange event in the search field.

solution

We can delay fetching data in RTK query until some condition becomes true. If you want to prevent a query from automatically running, you can use the skip parameter in a hook.

To achieve this we use a custom react hook useDebounce which will return the user input after 500ms.

This query will not run until the user types something into the search box.


const [searchQuery, setSearchQuery] = useState("");
// custom hook
const debouncedSearchQuery = useDebounce(searchQuery, 500);

  const {
    data: searchResult,
    isSuccess: searchedForMovie,
    isFetching,
    isError,
  } = useSearchMovieQuery(debouncedSearchQuery, { skip: debouncedSearchQuery === "" });

Enter fullscreen mode Exit fullscreen mode

Stackoverflow question: rtk-query-run-query-only-after-user-stops-typing-in-search-field

second question: How to disable RTK Query auto-request fetching?

You can learn more about useDebounce hook here

References

RTK query best practices

How to use transformResponse props with injectEndpoints

Thank You, Please follow me

Buy Me A Coffee

twitter
github
linkedin

Top comments (0)