DEV Community

Cover image for RTK Query Made Easy for Beginners šŸŽ“ (With Real-Life Analogies)
Kudzai Murimi
Kudzai Murimi Subscriber

Posted on

RTK Query Made Easy for Beginners šŸŽ“ (With Real-Life Analogies)

If you've ever felt intimidated by Redux Toolkit Query (RTK Query), you're not alone. The docs https://redux-toolkit.js.org/tutorials/rtk-query assume you already know what a "reducer" or "middleware" is — but what if you're brand new to this?

This article explains RTK Query using everyday analogies, so by the end you'll actually understand what's happening instead of just copy-pasting code.

Let's build a tiny app that shows a list of students from a server. šŸ§‘ā€šŸŽ“

The Big Picture

Imagine our school website asks a server:

"Can I have the list of students?"

And the server replies:

[
  { "id": 1, "name": "John" },
  { "id": 2, "name": "Mary" }
]
Enter fullscreen mode Exit fullscreen mode

RTK Query is the tool that handles that entire conversation for you — asking, waiting, and remembering the answer — so you don't have to write fetch() calls by hand.

Step 1: Project Structure

Here's what our project will look like:

src/
    App.jsx
    main.jsx
    store.js
    services/
        studentApi.js
Enter fullscreen mode Exit fullscreen mode

Think of it like a school: the School is your app, the Classroom is your store, and the Students are your data. Everything has its own place.

Step 2: Install Redux Toolkit

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

This gives you RTK Query for free — it's built right into @reduxjs/toolkit.

Step 3: Create the API Service

Create src/services/studentApi.js:

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

export const studentApi = createApi({
  reducerPath: "studentApi",

  baseQuery: fetchBaseQuery({
    baseUrl: "https://jsonplaceholder.typicode.com/",
  }),

  endpoints: (builder) => ({
    getStudents: builder.query({
      query: () => "users",
    }),
  }),
});

export const { useGetStudentsQuery } = studentApi;
Enter fullscreen mode Exit fullscreen mode

Let's break down every part of this, piece by piece.

createApi and fetchBaseQuery

Think of building a toy car — first you need your tools: a hammer, a screwdriver, a spanner. createApi and fetchBaseQuery are your tools for building an API layer.

reducerPath

Think of a cupboard with labelled shelves — one for books, one for toys, one for shoes. reducerPath: "studentApi" tells Redux: store all the student information on the "studentApi" shelf.

baseQuery

Imagine your friend lives at 12 Green Street. Every time you visit, you start from that same address. baseQuery works the same way — it's the address every request starts from:

https://jsonplaceholder.typicode.com/
Enter fullscreen mode Exit fullscreen mode

endpoints

Think of a restaurant menu: Pizza, Burger, Chicken, Juice — each dish is a menu item. In our app, each endpoint is one thing we can ask the server for: Get Students, Get Teachers, Delete Student, and so on.

builder.query()

This means "I only want to READ." It's like asking your teacher, "Can I see today's attendance list?" — you're not changing anything, just looking.

query: () => "users"

This tells RTK Query which path to visit. It joins the base URL and this path together:

https://jsonplaceholder.typicode.com/  +  users
=  https://jsonplaceholder.typicode.com/users
Enter fullscreen mode Exit fullscreen mode

That's the actual address it fetches.

Step 4: Add the API to Your Store

Create store.js:

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

export const store = configureStore({
  reducer: {
    [studentApi.reducerPath]: studentApi.reducer,
  },

  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(studentApi.middleware),
});
Enter fullscreen mode Exit fullscreen mode

Imagine your teacher asks, "Where should I keep the student register?" You say, "Put it in this cupboard." That's the reducer — it decides where the data lives.

Now imagine a school messenger: the teacher says, "Take this letter to Class 4," and the messenger delivers it. That messenger is the middleware — it carries requests to the server and brings the response back.

Step 5: Wrap Your App with Provider

import { Provider } from "react-redux";
import { store } from "./store";

<Provider store={store}>
  <App />
</Provider>;
Enter fullscreen mode Exit fullscreen mode

Think of electricity. Without it, your TV, fridge, and computer don't work. Provider supplies the Redux store to your entire app — without it, nothing connects.

Step 6: Use the Hook

Inside App.jsx:

import { useGetStudentsQuery } from "./services/studentApi";

function App() {
  const { data, isLoading, error } = useGetStudentsQuery();

  console.log(data);

  return <div>Hello</div>;
}
Enter fullscreen mode Exit fullscreen mode

The moment useGetStudentsQuery() runs, RTK Query automatically says "Hello server, can I have the students?" — no fetch(), no axios(). It's all handled for you.

Step 7: Understanding data

Imagine asking your mom, "Can I have some apples?" and she hands you a bag of šŸŽšŸŽšŸŽ. That bag is your data.

For our app, console.log(data) might print:

[
  { "id": 1, "name": "Leanne Graham" },
  { "id": 2, "name": "Ervin Howell" }
]
Enter fullscreen mode Exit fullscreen mode

Step 8: Understanding isLoading

Imagine ordering pizza. Before it arrives, you're waiting — that's isLoading. While it's on the way, isLoading is true. The moment it arrives, isLoading becomes false.

Step 9: Showing a Loading State

if (isLoading) {
  return <h1>Loading...</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Users see "Loading..." until the server responds.

Step 10: Understanding error

If the internet drops or the server fails to respond, error will contain details about what went wrong:

if (error) {
  return <h1>Something went wrong.</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Step 11: Rendering the Students

return (
  <div>
    {data.map((student) => (
      <h2 key={student.id}>{student.name}</h2>
    ))}
  </div>
);
Enter fullscreen mode Exit fullscreen mode

If the server returns John and Mary, the screen shows:

John
Mary
Enter fullscreen mode Exit fullscreen mode

What's Actually Happening Behind the Scenes?

šŸ‘¦ React: I need students.
      ↓
šŸ“ž RTK Query: I'll ask the server.
      ↓
🌐 Server: Here are the students.
      ↓
šŸ“¦ RTK Query: I'll save them.
      ↓
šŸ‘¦ React: Thank you! I'll show them.
Enter fullscreen mode Exit fullscreen mode

You never wrote fetch(). You never managed a loading flag by hand. You never stored the response yourself. RTK Query handled all of it.

One More Superpower: Caching

Imagine your teacher asks, "What's 2 + 2?" You answer "4." A minute later she asks again — you already know the answer, so you don't need to think about it again.

RTK Query behaves the same way:

First time:

React → Server → Data → Saved in cache
Enter fullscreen mode Exit fullscreen mode

Second time:

React → Cache āœ… (no new server request)
Enter fullscreen mode Exit fullscreen mode

This makes your app noticeably faster and cuts down on unnecessary network traffic.

Wrapping Up

That's the entire mental model of RTK Query:

  1. Define your API with createApi
  2. Register it in your store (reducer + middleware)
  3. Provide the store to your app
  4. Consume it with an auto-generated hook
  5. Let it cache so repeat requests are instant

Once this clicks, learning mutations (adding, updating, deleting data) is easy — they follow the exact same pattern, just with builder.mutation() instead of builder.query().

Happy coding! šŸš€

Top comments (2)

Collapse
 
frank_signorini profile image
Frank

How does RTK Query handle caching in real-world scenarios, I've had issues with it in the past. Would love to hear your thoughts on this.

Collapse
 
respect17 profile image
Kudzai Murimi

I took "real-world" to mean: not the toy example from the article, but what actually happens once you're building a real app with mutations, navigation, multiple users, etc.

I am not sure if thats the explanation you are looking forward to.