Multiple Parameters In Redux-Toolkit Query (RTK Query)
Tags: redux, react, tutorial, beginners
Published: 2022-11-17 07:41:32

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**: Redux-Toolkit Query accepts only one argument to pass, but there are some cases where you want to give multiple arguments. Currently, there has yet to be an official guide on this topic. So, how to pass multiple arguments?

**Solution**: Pass arguments as object.

**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.

```javascript
npm install @reduxjs/toolkit react-redux 
```

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

```javascript
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({
            // Accepts only single argument
            query: (user) => `users/${user}`
        }),
    })
});

// Export endpoints as hooks
export const { useGetUsersQuery } = api;
```

### store.js

```javascript
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)
    }
});
```

### index.js

```javascript
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>
);
```
## In General, Query using single parameter.
### App.js

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

function App() {
  const [userData, setUserData] = useState();
  // You can only pass one argument 🤔
  const { data } = useGetUsersQuery(1);

  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> 
      ))} 
    </div> 
  );
}

export default App;
```

## Solution: Pass argument as object.
Previously, we passed the single argument, which is the user number. Now, instead of hardcoding the "users" keyword in the api endpoints, We will use it as an argument along with the user number.
We have to make a slight change inside our **api.js** file to pass the argument as an object and return an object with a URL property.

### api.js

```javascript
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: (args) => {
                // Destructuring Object
                const { type, userNumber } = args;
                return {
                    // Returns url with multiple args
                    url: `${type}/${userNumber}`
                }
            }
        }),
    })
});

// Export endpoints as hooks
export const { useGetUsersQuery } = api;
```

Now we can use multiple arguments in our hook 😀. We have to pass it as an object. Let us see an example.

### App.js

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

function App() {
  const [userData, setUserData] = useState();
  // Passing multiple arguments as an object 😀
  const { data } = useGetUsersQuery({type: "users", userNumber: 1});

  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> 
      ))} 
    </div> 
  );
}

export default App;
```

We did it! 😄

Video Tutorial:
{% youtube HNc_yajEAtc %}

Thanks for reading! ♥