Redux Toolkit and RTK Query Bangla Tutorial,

React redux toolkit and RTK Query bangla tutorial

আজ আমরা আধুনিক ওয়েব ডেভেলপমেন্টের অন্যতম গুরুত্বপূর্ণ দুটি টুল—Redux Toolkit এবং RTK Query—সম্পর্কে বিস্তারিত জানব। এই গাইডটি নতুন এবং অভিজ্ঞ সকল ডেভেলপারের জন্য তৈরি করা হয়েছে।

১. ভূমিকা: কেন Redux এবং Redux Toolkit?

Redux কী?

Redux হলো একটি ওপেন-সোর্স জাভাস্ক্রিপ্ট লাইব্রেরি যা একটি অ্যাপ্লিকেশনের স্টেট (State) পরিচালনা করার জন্য ব্যবহৃত হয়। সহজ ভাষায়, এটি আপনার অ্যাপ্লিকেশনের সমস্ত ডেটাকে একটি কেন্দ্রীয় স্থানে জমা রাখে, যাকে Store বলা হয়। এর ফলে ডেটা ম্যানেজমেন্ট অনেক সহজ এবং অনুমানযোগ্য (predictable) হয়।

সমস্যা: Prop Drilling

সাধারণত React অ্যাপ্লিকেশনে, ডেটা একটি কম্পোনেন্ট থেকে তার চাইল্ড কম্পোনেন্টে props-এর মাধ্যমে পাঠানো হয়। কিন্তু যখন একটি ডেটা অনেকগুলো লেভেল নিচে থাকা কোনো কম্পোনেন্টে পাঠাতে হয়, তখন মাঝের প্রত্যেকটি কম্পোনেন্টের মধ্য দিয়ে সেই ডেটা পাস করতে হয়, যদিও তাদের ওই ডেটার কোনো প্রয়োজনই নেই। এই সমস্যাটিকে Prop Drilling বলা হয়।

উপরের ছবিতে দেখুন, App কম্পোনেন্টের ডেটা Data কম্পোনেন্টে পাঠাতে হলে CardUser কম্পোনেন্টের মধ্য দিয়ে পাস করতে হচ্ছে। এটি কোডকে জটিল এবং রক্ষণাবেক্ষণে কঠিন করে তোলে।

সমাধান: Redux Toolkit

Redux এই সমস্যার সমাধান করে একটি কেন্দ্রীয় Store তৈরি করার মাধ্যমে। এতে যেকোনো কম্পোনেন্ট সরাসরি Store থেকে ডেটা নিতে পারে।

Redux Toolkit (RTK) হলো Redux টিম কর্তৃক প্রস্তাবিত Redux ব্যবহারের অফিসিয়াল এবং সবচেয়ে কার্যকর উপায়। এটি Redux-এর জটিলতা কমিয়ে দেয় এবং бойলারপ্লেট কোড লেখা থেকে মুক্তি দেয়। এর প্রধান দুটি উদ্দেশ্য হলো:

  1. স্টেট ম্যানেজমেন্টকে সহজ করা (Makes State Management Easy)।
  2. Redux-এর সাথে কাজ করা সহজ করা (Makes Redux Easy To Work With)।

২. Redux Toolkit (RTK) সেটআপ এবং ব্যবহার

এই অংশে আমরা ধাপে ধাপে একটি React অ্যাপ্লিকেশনে Redux Toolkit সেটআপ করব।

ধাপ ১: প্রজেক্ট তৈরি এবং ইন্সটলেশন

প্রথমে Vite ব্যবহার করে একটি নতুন React প্রজেক্ট তৈরি করুন:

npx create-vite my-rdx-app --template react
cd my-rdx-app

এরপর প্রয়োজনীয় দুটি প্যাকেজ ইন্সটল করুন:

npm install @reduxjs/toolkit react-redux
  • @reduxjs/toolkit: মূল RTK লাইব্রেরি।
  • react-redux: React অ্যাপ্লিকেশনের সাথে Redux বাইন্ড করার জন্য।

ধাপ ২: Store তৈরি করা

Store হলো আমাদের অ্যাপ্লিকেশনের সম্পূর্ণ স্টেটের ধারক। src ফোল্ডারের ভেতরে app নামে একটি ফোল্ডার এবং তার ভেতরে store.js নামে একটি ফাইল তৈরি করুন।

src/app/store.js

import { configureStore } from '@reduxjs/toolkit';
 
export const store = configureStore({
  reducer: {
    // আমাদের reducer গুলো এখানে যুক্ত হবে
  },
});

configureStore ফাংশনটি একটি reducer অবজেক্ট গ্রহণ করে এবং স্বয়ংক্রিয়ভাবে Redux Store তৈরি করে।

ধাপ ৩: React অ্যাপে Store যুক্ত করা

এবার আমাদের React অ্যাপকে Store সম্পর্কে জানাতে হবে। এর জন্য Provider কম্পোনেন্ট ব্যবহার করা হয়।

src/main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import './index.css';
import { store } from './app/store';
import { Provider } from 'react-redux';
 
ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
);

Provider কম্পোনেন্টটি পুরো অ্যাপকে র‍্যাপ করে এবং store prop হিসেবে গ্রহণ করে, যার ফলে অ্যাপের যেকোনো জায়গা থেকে Store অ্যাক্সেস করা যায়।

ধাপ ৪: Slice তৈরি করা

একটি Slice হলো অ্যাপ্লিকেশনের স্টেটের একটি অংশ এবং সেই স্টেট আপডেট করার লজিক (reducer)। src ফোল্ডারে features/counter নামে একটি ফোল্ডার তৈরি করুন এবং তার ভেতরে counterSlice.js ফাইল তৈরি করুন।

src/features/counter/counterSlice.js

import { createSlice } from '@reduxjs/toolkit';
 
const initialState = {
  value: 0,
};
 
export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});
 
// প্রতিটি reducer ফাংশনের জন্য Action Creator তৈরি করা হয়
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
 
export default counterSlice.reducer;

createSlice ফাংশনটি স্বয়ংক্রিয়ভাবে যা যা করে:

  • name এবং initialState ব্যবহার করে একটি স্লাইস তৈরি করে।
  • reducers অবজেক্টের প্রতিটি ফাংশনের জন্য একটি Action Creator তৈরি করে।
  • Immer লাইব্রেরি ব্যবহার করার ফলে আমরা সরাসরি স্টেট পরিবর্তন করতে পারি (যেমন state.value += 1), যা কোডকে সহজ করে।

ধাপ ৫: Store-এ Slice Reducer যুক্ত করা

তৈরি করা Slice-টিকে আমাদের Store-এর সাথে যুক্ত করতে হবে।

src/app/store.js

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice'; // ইম্পোর্ট করুন
 
export const store = configureStore({
  reducer: {
    counter: counterReducer, // reducer যুক্ত করুন
  },
});

ধাপ ৬: React কম্পোনেন্টে State এবং Action ব্যবহার করা

এখন আমরা আমাদের React কম্পোনেন্ট থেকে Store-এর ডেটা পড়ব এবং তাকে পরিবর্তন করব।

  • useSelector: Store থেকে ডেটা পড়ার জন্য।
  • useDispatch: Actions পাঠানোর জন্য।

src/features/counter/Counter.jsx (নতুন কম্পোনেন্ট)

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { decrement, increment } from './counterSlice';
 
export function Counter() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();
 
  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          +
        </button>
        <span>{count}</span>
        <button
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          -
        </button>
      </div>
    </div>
  );
}

এখানে, useSelector দিয়ে আমরা counter স্লাইসের value পড়ছি এবং useDispatch দিয়ে incrementdecrement action পাঠাচ্ছি।


৩. RTK Query: ডেটা ফেচিং এবং ক্যাশিং-এর আধুনিক উপায়

RTK Query হলো Redux Toolkit-এর একটি শক্তিশালী অংশ যা সার্ভার থেকে ডেটা আনা (fetching), ক্যাশ (caching), এবং আপডেট করার কাজটিকে অবিশ্বাস্যভাবে সহজ করে তোলে। এটি স্বয়ংক্রিয়ভাবে লোডিং, এরর এবং ডেটা স্টেট পরিচালনা করে, যার ফলে আমাদের ম্যানুয়ালি অনেক কোড লিখতে হয় না।

ধাপ ১: একটি API Slice তৈরি করা

আমরা একটি নতুন API Slice তৈরি করব যা সার্ভারের সাথে যোগাযোগ করবে।

src/features/api/apiSlice.js

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
 
export const apiSlice = createApi({
  reducerPath: 'api', // Store-এ reducer-এর নাম
  baseQuery: fetchBaseQuery({ baseUrl: 'https://jsonplaceholder.typicode.com' }),
  endpoints: (builder) => ({
    getPosts: builder.query({
      query: () => '/posts', // URL-এর শেষ অংশ
    }),
    getPostById: builder.query({
      query: (id) => `/posts/${id}`,
    }),
    addNewPost: builder.mutation({
      query: (initialPost) => ({
        url: '/posts',
        method: 'POST',
        body: initialPost,
      }),
    }),
  }),
});
 
// RTK Query স্বয়ংক্রিয়ভাবে প্রতিটি endpoint-এর জন্য কাস্টম হুক তৈরি করে
export const { useGetPostsQuery, useGetPostByIdQuery, useAddNewPostMutation } = apiSlice;
  • createApi: API service তৈরির মূল ফাংশন।
  • fetchBaseQuery: fetch এর একটি লাইটওয়েট র‍্যাপার।
  • endpoints: এখানে আমরা API-এর বিভিন্ন অপারেশন (ডেটা পড়া বা পরিবর্তন করা) ডিফাইন করি।
    • query: ডেটা পড়ার জন্য (GET)।
    • mutation: ডেটা পরিবর্তন করার জন্য (POST, PUT, DELETE)।

ধাপ ২: Store-এ API Slice যুক্ত করা

এই API service-টিকেও Store-এর সাথে যুক্ত করতে হবে।

src/app/store.js

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
import { apiSlice } from '../features/api/apiSlice'; // ইম্পোর্ট করুন
 
export const store = configureStore({
  reducer: {
    counter: counterReducer,
    [apiSlice.reducerPath]: apiSlice.reducer, // API reducer যুক্ত করুন
  },
  // middleware যুক্ত করা RTK Query-এর ক্যাশিং এবং অন্যান্য ফিচারের জন্য জরুরি
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(apiSlice.middleware),
});

ধাপ ৩: React কম্পোনেন্টে RTK Query হুক ব্যবহার করা

এবার আমরা কম্পোনেন্টে স্বয়ংক্রিয়ভাবে তৈরি হওয়া হুকগুলো ব্যবহার করে ডেটা প্রদর্শন করব।

src/features/posts/PostsList.jsx (নতুন কম্পোনেন্ট)

import React from 'react';
import { useGetPostsQuery } from '../api/apiSlice';
 
const PostsList = () => {
  const {
    data: posts,
    isLoading,
    isSuccess,
    isError,
    error,
  } = useGetPostsQuery();
 
  let content;
 
  if (isLoading) {
    content = <p>"Loading..."</p>;
  } else if (isSuccess) {
    content = posts.map((post) => (
      <article key={post.id}>
        <h3>{post.title}</h3>
        <p>{post.body.substring(0, 100)}</p>
      </article>
    ));
  } else if (isError) {
    content = <div>{error.toString()}</div>;
  }
 
  return (
    <section>
      <h2>Posts</h2>
      {content}
    </section>
  );
};
 
export default PostsList;

দেখুন, useGetPostsQuery হুকটি স্বয়ংক্রিয়ভাবে data, isLoading, isSuccess, isError ইত্যাদি স্টেট রিটার্ন করছে। আমাদের আর ম্যানুয়ালি useEffect বা useState দিয়ে এগুলো ম্যানেজ করতে হচ্ছে না।


উপসংহার

Redux Toolkit এবং RTK Query আধুনিক React অ্যাপ্লিকেশন তৈরির প্রক্রিয়াকে অনেক সহজ এবং শক্তিশালী করে তুলেছে। бойলারপ্লেট কোড কমিয়ে এবং ডেটা ফেচিং-এর মতো জটিল কাজগুলোকে স্বয়ংক্রিয় করে এটি ডেভেলপারদের প্রোডাক্টিভিটি বাড়াতে সাহায্য করে। আশা করি এই comprehensive গাইডটি আপনাকে Redux Toolkit এবং RTK Query আয়ত্ত করতে সাহায্য করবে। শুভ কোডিং! 🚀

http://googleusercontent.com/youtube_content/0 (opens in a new tab)


© 2025 React JS Bangla Tutorial.