Redux Toolkit Query (RTK Query): The Modern Way to Fetch, Cache, and Synchronize Data in React Applications
React application বানাতে গিয়ে একটা সময় প্রায় সবাই একই সমস্যার মুখোমুখি হয় — API call manage করা, loading state handle করা, error manage করা, caching implement করা, এবং data synchronization ঠিক রাখা।
আমিও যখন Redux Toolkit ব্যবহার শুরু করি, তখন API fetching-এর জন্য আলাদা service layer, thunk, reducer, action, loading state — সবকিছু maintain করতে হতো। ছোট project-এ manageable হলেও application বড় হওয়ার সাথে সাথে codebase জটিল হতে শুরু করে।
ঠিক এই জায়গাতেই RTK Query game changer হিসেবে আসে।
RTK Query Redux Toolkit-এর built-in data fetching এবং caching solution, যা API-related boilerplate code নাটকীয়ভাবে কমিয়ে দেয় এবং application performance improve করতে সাহায্য করে।
RTK Query কী?
RTK Query হলো Redux Toolkit-এর উপর built করা একটি powerful data fetching and caching library।
এটি API request, caching, loading state, error handling, automatic refetching, polling, optimistic update এবং cache invalidation-এর মতো feature built-in ভাবে provide করে।
সহজ ভাষায় বলতে গেলে:
RTK Query আপনার API communication layer-এর প্রায় ৮০% repetitive কাজ নিজের দায়িত্বে নিয়ে নেয়।
কেন RTK Query ব্যবহার করবেন?
অনেক developer এখনো Axios + Redux Thunk combination ব্যবহার করেন। এটা অবশ্যই কাজ করে।
কিন্তু একটু compare করি।
Traditional Redux Approach
API Call
↓
Action Create
↓
Thunk Create
↓
Reducer Update
↓
Loading State
↓
Error State
↓
Store Update
↓
Component Re-renderএকটা simple API fetch করতেই কয়েকটা file তৈরি করতে হয়।
RTK Query Approach
API Endpoint Define
↓
Auto Generated Hook
↓
Done ✅এতটাই simple।
RTK Query-এর Core Benefits
1. Automatic Caching
একবার data fetch হলে RTK Query সেটা cache করে রাখে।
const { data } = useGetUsersQuery();একই component বা অন্য page থেকে আবার request গেলে RTK Query cache ব্যবহার করবে।
ফলে:
- কম network request
- দ্রুত response
- ভালো user experience
2. Built-in Loading & Error State
আগে:
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);RTK Query:
const {
data,
isLoading,
isFetching,
error,
} = useGetUsersQuery();সবকিছু built-in।
3. Automatic Refetching
User page revisit করলে data automatically refresh করা যায়।
useGetUsersQuery(undefined, {
refetchOnFocus: true,
});Browser tab focus হলেই data update হবে।
4. Request Deduplication
ধরুন একই page-এ তিনটা component একই API call করছে।
RTK Query:
3 Components
↓
1 Network Request
↓
Shared Cacheএকই request বারবার পাঠাবে না।
5. TypeScript Experience
RTK Query TypeScript-এর সাথে অসাধারণ কাজ করে।
type User = {
id: string;
name: string;
};getUsers: builder.query<User[], void>({
query: () => "/users",
});এরপর component-এ auto type inference পাওয়া যায়।
Project Structure
আমার ব্যক্তিগত project-গুলোতে সাধারণত structure এমন থাকে:
src
│
├── redux
│ ├── store.ts
│ ├── api
│ │ ├── baseApi.ts
│ │ ├── userApi.ts
│ │ ├── authApi.ts
│ │ └── blogApi.ts
│
├── pages
├── components
└── typesBase API Setup
RTK Query setup-এর প্রথম ধাপ হলো base API create করা।
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";export const baseApi = createApi({
reducerPath: "api",
baseQuery: fetchBaseQuery({
baseUrl: "https://api.example.com",
}),
tagTypes: ["User", "Blog"],
endpoints: () => ({}),
});এখানে:
reducerPathRedux store key define করেbaseQueryAxios-এর বিকল্প lightweight fetch wrappertagTypescache invalidation-এর জন্য ব্যবহার হয়
Store Configuration
import { configureStore } from "@reduxjs/toolkit";
import { baseApi } from "./api/baseApi";export const store = configureStore({
reducer: {
[baseApi.reducerPath]: baseApi.reducer,
}, middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(baseApi.middleware),
});
অনেক developer middleware add করতে ভুলে যায়।
ফলে RTK Query কাজ করলেও caching, refetching, polling-এর মতো feature কাজ করে না।
Creating Query Endpoints
ধরুন users fetch করতে হবে।
const userApi = baseApi.injectEndpoints({
endpoints: (builder) => ({
getUsers: builder.query({
query: () => "/users",
}),
}),
});export const {
useGetUsersQuery,
} = userApi;RTK Query automatically hook generate করবে।
Using Query Hook
const UsersPage = () => {
const {
data,
isLoading,
error,
} = useGetUsersQuery();if (isLoading) {
return <p>Loading...</p>;
} if (error) {
return <p>Something went wrong</p>;
} return (
<>
{data?.map((user) => (
<div key={user.id}>
{user.name}
</div>
))}
</>
);
};
এখানে manually state manage করার প্রয়োজন নেই।
Mutation: Create, Update, Delete
Data modify করার জন্য mutation ব্যবহার করা হয়।
createUser: builder.mutation({
query: (data) => ({
url: "/users",
method: "POST",
body: data,
}),
}),Hook:
const [createUser, { isLoading }] =
useCreateUserMutation();Usage:
await createUser({
name: "Anas",
});Cache Invalidation: The Real Superpower
অনেক developer RTK Query ব্যবহার করে কিন্তু cache invalidation properly ব্যবহার করে না।
Get Ariyan Rahman Anas’s stories in your inbox
Join Medium for free to get updates from this writer.
ধরুন user create করার পর users list automatically refresh করতে হবে।
getUsers: builder.query({
query: () => "/users",
providesTags: ["User"],
}),createUser: builder.mutation({
query: (data) => ({
url: "/users",
method: "POST",
body: data,
}), invalidatesTags: ["User"],
}),এখন:
Create User
↓
Invalidate User Cache
↓
Auto Refetch Users
↓
UI Updatedকোন manual refetch লাগবে না।
Authentication Integration
Real-world project-এ JWT token handle করতে হয়।
আমি সাধারণত এভাবে করি:
baseQuery: fetchBaseQuery({
baseUrl: API_URL,prepareHeaders: (headers) => {
const token =
localStorage.getItem("accessToken"); if (token) {
headers.set(
"Authorization",
`Bearer ${token}`
);
} return headers;
},
}),
এভাবে সব request-এ token automatically attach হবে।
Token Refresh Strategy
Production application-এ access token expire হওয়া খুবই common।
একটা scalable approach:
Request
↓
401 Error
↓
Refresh Token Request
↓
New Access Token
↓
Retry Original Requestএটা custom baseQuery wrapper দিয়ে implement করা যায়।
এর ফলে user বারবার login page-এ redirect হয় না।
Optimistic Update
User experience improve করার অন্যতম সেরা technique।
ধরুন user “Like” button press করেছে।
Traditional flow:
Click Like
↓
Wait API
↓
Update UIOptimistic flow:
Click Like
↓
Update UI Instantly
↓
Send API Request
↓
Rollback if FailedRTK Query এটা খুব সুন্দরভাবে support করে।
onQueryStarted(
postId,
{ dispatch, queryFulfilled }
) {
const patchResult =
dispatch(
api.util.updateQueryData(
"getPosts",
undefined,
(draft) => {
const post =
draft.find(
p => p.id === postId
);if(post){
post.likes++;
}
}
)
); try {
await queryFulfilled;
} catch {
patchResult.undo();
}
}
এটা social media, e-commerce, dashboard application-এ অত্যন্ত useful।
Polling
যখন real-time feeling দরকার হয়:
const { data } =
useGetNotificationsQuery(
undefined,
{
pollingInterval: 5000,
}
);প্রতি ৫ সেকেন্ডে data refresh হবে।
Common Mistakes Developers Make
1. Everything in Redux Store রাখা
অনেক developer API data manually Redux slice-এ copy করে।
এটা unnecessary।
RTK Query already cache manage করে।
2. Not Using Tags
invalidatesTags
providesTagsঠিকভাবে ব্যবহার না করলে automatic refetch-এর সুবিধা পাওয়া যায় না।
3. Creating Multiple Base APIs
অনেক project-এ দেখি:
authApi
userApi
blogApi
productApiপ্রত্যেকটার জন্য আলাদা createApi।
এটা maintainability কমিয়ে দেয়।
সাধারণত একটি base API create করে injectEndpoints() ব্যবহার করাই ভালো approach।
4. Overusing Refetch
অনেকে mutation success হওয়ার পর manually:
refetch();call করে।
যখন tag invalidation ব্যবহার করলেই একই কাজ automatic হয়ে যায়।
RTK Query বনাম React Query
এই প্রশ্নটা প্রায়ই আসে।
React Query
ভালো যদি:
- Redux ব্যবহার না করেন
- Smaller application হয়
RTK Query
ভালো যদি:
- Redux Toolkit already ব্যবহার করেন
- Centralized state management দরকার হয়
- Large scale application হয়
আমার অভিজ্ঞতায়, Redux Toolkit-based project হলে RTK Query প্রায় সবক্ষেত্রেই cleaner solution।
বাস্তব অভিজ্ঞতা থেকে কিছু কথা
প্রথম যখন RTK Query ব্যবহার শুরু করি, সবচেয়ে বড় পরিবর্তন ছিল boilerplate code dramatically কমে যাওয়া।
আগে যেখানে একটি feature implement করতে action, reducer, thunk, selector মিলিয়ে কয়েকশো লাইন code লিখতে হতো, এখন একই কাজ অনেক কম code-এ করা যায়।
তার থেকেও গুরুত্বপূর্ণ বিষয় হলো caching এবং synchronization নিয়ে আর আলাদা করে চিন্তা করতে হয় না। Application বড় হওয়ার সাথে সাথে এই সুবিধাগুলোর মূল্য আরও বেশি বোঝা যায়।
RTK Query শুধু data fetch করার library না — এটা API state management-এর একটা complete ecosystem।
উপসংহার
যদি আপনি Redux Toolkit ব্যবহার করেন কিন্তু এখনো RTK Query adopt না করে থাকেন, তাহলে এখনই সময় বিষয়টা গুরুত্ব দিয়ে দেখার।
কারণ modern React application-এ challenge আর শুধু data fetch করা নয়; challenge হলো efficient caching, synchronization, scalability এবং maintainability নিশ্চিত করা।
RTK Query এই চারটি সমস্যারই একটি পরিণত এবং production-ready সমাধান।
একবার project-এ properly integrate করতে পারলে, API management নিয়ে আপনার ভাবনা অনেকটাই বদলে যাবে। শুধু কম code লেখার জন্য নয়, বরং cleaner architecture এবং long-term maintainability-এর জন্যও RTK Query বর্তমানে React ecosystem-এর সবচেয়ে শক্তিশালী data-fetching solutionগুলোর একটি।






