Workstation Logo
পণ্য
এআই ল্যাবসOpenAI এজেন্টClaude এজেন্টGrok BotWorkstation CRM (WSL CRM)মার্কেটিংসব পণ্য
এআই সমাধান
এআই ওয়ার্কস্টেশনAI SME Packagesপ্রাইভেট এআইজিপিইউ ক্লাস্টারএজ এআইএন্টারপ্রাইজ এআই ল্যাবশিল্প অনুযায়ী এআই
সেবাসমূহ
Platform ModernisationDigital EngineeringData Foundations & AIAutonomous Operationsএআই পরামর্শDevOps অটোমেশনসাইবার নিরাপত্তাসফটওয়্যার ডেভেলপমেন্টএজেন্ট নির্মাণMLOps সেটআপ
আমাদের সম্পর্কে
অংশীদারগ্রাহক গল্প
প্রবন্ধ
ডকুমেন্টেশন
WSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7
ব্লগ
যোগাযোগ করুনLogin
Workstation

আধুনিক ব্যবসার জন্য AI ওয়ার্কস্টেশন, AI মাল্টি-এজেন্টিক সফটওয়্যার, GPU অবকাঠামো এবং বুদ্ধিমান এজেন্ট সমাধান।

যোগাযোগ করুন

AI সমাধান

এআই ওয়ার্কস্টেশনAI SME Packagesপ্রাইভেট এআইজিপিইউ ক্লাস্টারএজ এআইএন্টারপ্রাইজ এআই ল্যাবশিল্প অনুযায়ী এআই

পণ্য

সব পণ্যWSL CRM ও ERPমার্কেটিংOpenAI এজেন্টWSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7

কোম্পানি

আমাদের সম্পর্কেকেন Workstationঅংশীদারগ্রাহক গল্পমূল্যযোগাযোগ

রিসোর্স

প্রবন্ধডকুমেন্টেশনব্লগখুঁজুনসাইটম্যাপ
যুক্তরাজ্য অফিস
77-79 Marlowes, Hemel Hempstead HP1 1LFদিকনির্দেশ - M25 আউটার লন্ডন থেকে জংশন ২০ নিনকোম্পানি নং: 11641870সোম - শুক্র: সকাল ৯:০০ - সন্ধ্যা ৬:০০ GMT
+44 7515 356 146
বেলজিয়াম অফিস
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683সোম - শুক্র: সকাল ৯:০০ - সন্ধ্যা ৬:০০ CET
+32 492 45 67 46
ভারত অফিস
#159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

© 2026 Workstation AI। সর্বস্বত্ব সংরক্ষিত।

গোপনীয়তাকুকিসেবার শর্তাবলীওয়েবসাইট সাইটম্যাপ

Loading blog...

Home / Blog
WebFrontendReact

অ্যাডভান্সড স্টেট ম্যানেজমেন্ট ইন রিঅ্যাক্ট: কাজের জন্য সঠিক টুল বেছে নেওয়া

Redux Toolkit, Zustand, Jotai, TanStack ক্যোয়ারী এবং রিঅ্যাক্ট কনটেক্সটের একটি ব্যবহারিক নির্দেশিকা — বাস্তব-বিশ্বের আর্কিটেকচার নিদর্শন এবং কর্মক্ষমতা কৌশল সহ

Balinder Walia২৭ মে, ২০২৫13 min read

রাজ্য ব্যবস্থাপনা প্রতিটি অ-তুচ্ছ প্রতিক্রিয়া অ্যাপ্লিকেশনের কেন্দ্রে বসে। এটি সঠিকভাবে পান এবং আপনার কোডবেস স্কেল করে এটি ভুল হয়ে যায় এবং আপনি প্রপ-ড্রিলিং দুঃস্বপ্ন, বাসি UI এবং উপাদানগুলি বিস্মৃতিতে নিজেকে পুনরায় রেন্ডার করার সাথে শেষ করেন। ভাল খবর হল প্রতিক্রিয়া বাস্তুতন্ত্র নাটকীয়ভাবে পরিপক্ক হয়েছে। আপনার কাছে এখন উদ্দেশ্য-নির্মিত সরঞ্জামগুলির একটি সমৃদ্ধ মেনু রয়েছে — Redux Toolkit, Zustand, Jotai, TanStack Query, এবং অন্তর্নির্মিত প্রসঙ্গ API — প্রতিটি সমস্যার একটি নির্দিষ্ট শ্রেণীর জন্য অপ্টিমাইজ করা হয়েছে৷

এই নিবন্ধটি প্রতিটি সমাধানের গভীরতার মধ্যে চলে, কংক্রিট উদাহরণ সহ ট্রেড-অফগুলি ব্যাখ্যা করে এবং আপনাকে একটি সিদ্ধান্ত কাঠামো দেয় যা আপনি আপনার নিজের প্রকল্পগুলিতে অবিলম্বে প্রয়োগ করতে পারেন।

রাজ্যের বিভিন্ন ধরনের বোঝা

রাজ্য ব্যবস্থাপনা ল্যান্ডস্কেপ প্রতিক্রিয়াউপাদান গাছঅ্যাপপৃষ্ঠা কপৃষ্ঠা বিCompCompCompCompuseState এখানে বাস করেপ্রতিটি উপাদান স্থানীয়useState / useReducerসুযোগ: একক উপাদানড্রপডাউন, ইনপুট, ফর্ম ক্ষেত্র, টগলপ্রসঙ্গ প্রতিক্রিয়াস্কোপ: সাবট্রি / অ্যাপ-ওয়াইড (কম ফ্রিকোয়েন্সি)থিম, লোকেল, অথ ইউজার, ফিচার ফ্ল্যাগRedux টুলকিটসুযোগ: DevTools সহ গ্লোবাল স্টোরজটিল অবস্থা, মিডলওয়্যার, সময় ভ্রমণজুস্ট্যান্ডলাইটওয়েটগ্লোবাল স্টোরজোতাইপারমাণবিক অবস্থাসূক্ষ্ম দানাদারTanStack ক্যোয়ারী - সার্ভার স্টেটআনয়ন, ক্যাশিং, সিঙ্ক্রোনাইজেশন, ব্যাকগ্রাউন্ড রিফ্রেশ, আশাবাদী আপডেটAPI প্রতিক্রিয়া, পেজিনেটেড তালিকা, রিয়েল-টাইম ডেটাস্থানীয়রাজ্যের সুযোগগ্লোবালরাজ্য ব্যবহার করুনপ্রসঙ্গজুস্ট্যান্ডজোতাইরেডাক্স

কোনো লাইব্রেরিতে পৌঁছানোর আগে, আপনি আসলে কোন ধরনের রাষ্ট্র পরিচালনা করছেন সে সম্পর্কে সুনির্দিষ্ট হওয়া মূল্যবান। বিভিন্ন রাজ্যের বিভাগগুলিকে সংঘটিত করা বেশিরভাগ ওভার-ইঞ্জিনিয়ারড রিঅ্যাক্ট অ্যাপ্লিকেশনের মূল কারণ।

  • স্থানীয় UI অবস্থা — একটি ড্রপডাউন খোলা আছে কিনা, কোন ট্যাব সক্রিয়, একটি নিয়ন্ত্রিত ইনপুটের বর্তমান মান। এই রাজ্যটি একটি একক উপাদান বা একটি ছোট উপবৃক্ষের মালিকানাধীন।
  • শেয়ার্ড ক্লায়েন্ট স্টেট — ডেটা যা একাধিক, সম্ভাব্য দূরবর্তী উপাদান পড়তে বা লিখতে হবে: বর্তমানে প্রমাণীকৃত ব্যবহারকারী, থিম পছন্দ, একটি শপিং কার্ট।
  • সার্ভারের অবস্থা — যে ডেটা সার্ভারে উৎপন্ন হয়, প্রকৃতির দ্বারা অ্যাসিঙ্ক্রোনাস, এবং ক্যাশে অকার্যকরকরণ, ব্যাকগ্রাউন্ড রি-ফেচিং এবং লোডিং/ত্রুটি জীবনচক্র ব্যবস্থাপনা প্রয়োজন।
  • URL অবস্থা — ফিল্টার, পেজিনেশন এবং সার্চ টার্ম যা একটি পৃষ্ঠা রিফ্রেশ করে বেঁচে থাকা উচিত এবং একটি লিঙ্কের মাধ্যমে শেয়ার করা যায়।
  • ফর্ম রাজ্য — নিয়ন্ত্রিত ইনপুট, বৈধতা ত্রুটি, এবং জমার স্থিতি, প্রায়শই একটি ডেডিকেটেড লাইব্রেরি যেমন প্রতিক্রিয়া হুক ফর্ম দ্বারা সর্বোত্তমভাবে পরিচালনা করা হয়।

আপনি করতে পারেন একক সবচেয়ে প্রভাবশালী জিনিস একটি বিশ্বব্যাপী দোকানে রাজ্যের প্রতিটি বিভাগ ঢালা তাগিদ প্রতিহত করা. প্রতিটি বিভাগে বিভিন্ন সামঞ্জস্যের প্রয়োজনীয়তা, বিভিন্ন জীবনকাল এবং বিভিন্ন আপডেট ফ্রিকোয়েন্সি রয়েছে।

প্রতিক্রিয়া প্রসঙ্গ: অন্তর্নির্মিত বিকল্প

প্রসঙ্গ API রিঅ্যাক্ট সহ পাঠানো হয় এবং এর জন্য কোন অতিরিক্ত নির্ভরতার প্রয়োজন হয় না। এটি রাজ্যের জন্য ভাল কাজ করে যা কদাচিৎ পরিবর্তিত হয় এবং অনেক উপাদান দ্বারা গ্রাস করা হয় — ক্লাসিক উদাহরণ হল থিম, লোকেল এবং প্রমাণীকৃত ব্যবহারকারী অবজেক্ট।

// AuthContext.tsx
import { createContext, useContext, useState, ReactNode } from 'react';

interface AuthState {
  user: User | null;
  login: (credentials: Credentials) => Promise<void>;
  logout: () => void;
}

const AuthContext = createContext<AuthState | null>(null);

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  const login = async (credentials: Credentials) => {
    const user = await authService.login(credentials);
    setUser(user);
  };

  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used inside AuthProvider');
  return ctx;
}

প্রসঙ্গ কর্মক্ষমতা ফাঁদ

প্রসঙ্গটির একটি সুপরিচিত কর্মক্ষমতা বৈশিষ্ট্য রয়েছে যা অনেক ডেভেলপারকে নিয়ে যায়: যখনই প্রসঙ্গ মান রেফারেন্স পরিবর্তিত হয় তখন প্রত্যেক গ্রাহক পুনরায় রেন্ডার করে। আপনি যদি একটি বড়, ঘন ঘন পরিবর্তিত বস্তু একটি একক প্রসঙ্গে সংরক্ষণ করেন, তাহলে আপনি আপনার পুরো গাছ জুড়ে অপ্রয়োজনীয় রি-রেন্ডারগুলিকে ট্রিগার করবেন।

প্রশমন কৌশলগুলি হল:

  • আপডেট ফ্রিকোয়েন্সি দ্বারা প্রসঙ্গ বিভক্ত করুন। ব্যবহারকারীর অবজেক্টকে একটি প্রসঙ্গে এবং UI পছন্দগুলি অন্যটিতে রাখুন।
  • এর সাথে মান অবজেক্ট মেমোাইজ করুন useMemo তাই তথ্য আসলে পরিবর্তিত হলেই রেফারেন্স পরিবর্তন হয়।
  • ব্যবহার করুন React.memo কনজিউমার কম্পোনেন্টে রি-রেন্ডার এড়িয়ে যাওয়ার জন্য যখন তারা যত্নশীল প্রপস পরিবর্তন করেনি।

সৎ উপসংহার হল কম-ফ্রিকোয়েন্সি গ্লোবাল স্টেটের জন্য কনটেক্সট চমৎকার, কিন্তু এটি একটি সাধারণ-উদ্দেশ্য রাষ্ট্র পরিচালনার সমাধান নয়। কনটেক্সট-এর রি-রেন্ডার আচরণের আশেপাশে কাজ করার জন্য আপনি নিজেকে বিস্তৃত মেমোাইজেশন লিখতে পেলে, এটি একটি ডেডিকেটেড লাইব্রেরিতে পৌঁছানোর সময়।

Redux টুলকিট: পরিপক্ক এন্টারপ্রাইজ চয়েস

রেডক্স টুলকিট — একমুখী ডেটা ফ্লোঅ্যাকশন স্রষ্টাপ্রেরণমিডলওয়্যারthunk / saga / loggerহ্রাসকারীদোকানসত্যের একক উৎসনির্বাচককম্পোনেন্টUI পুনরায় রেন্ডার করেপ্রেরণ (ক্রিয়া)মাধ্যমে পাসক্রিয়া প্রসেস করেনতুন রাষ্ট্র ফিরিয়ে দেয়তথ্য আহরণ করেআপডেট ভিউব্যবহারকারীর মিথস্ক্রিয়াRedux DevToolsটাইম-ট্রাভেল ডিবাগিং এবং রাষ্ট্রীয় পরিদর্শন

বয়লারপ্লেটের জন্য Redux-এর একটি খ্যাতি রয়েছে — একটি খ্যাতি এটি প্রাক-টুলকিট যুগে অর্জিত হয়েছিল। Redux Toolkit (RTK) অনুষ্ঠানটি বাদ দেয় যখন Redux কে শক্তিশালী করে তোলে: একটি একক, অনুমানযোগ্য, পরিদর্শনযোগ্য স্টেট ট্রি কঠোর একমুখী ডেটা প্রবাহ সহ।

RTK জাহাজ createSlice, যা একটি একক সংজ্ঞা থেকে অ্যাকশন ক্রিয়েটর এবং রিডিউসার তৈরি করে এবং হুডের নীচে ইমার ব্যবহার করে যাতে আপনি এমন মিউটেশন লিখতে পারেন যেগুলি অপরিহার্য দেখায় কিন্তু বাস্তবে অপরিবর্তনীয়ভাবে প্রয়োগ করা হয়।

// features/cart/cartSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface CartItem {
  id: string;
  name: string;
  quantity: number;
  price: number;
}

interface CartState {
  items: CartItem[];
  coupon: string | null;
}

const initialState: CartState = { items: [], coupon: null };

export const cartSlice = createSlice({
  name: 'cart',
  initialState,
  reducers: {
    addItem(state, action: PayloadAction<CartItem>) {
      const existing = state.items.find(i => i.id === action.payload.id);
      if (existing) {
        existing.quantity += action.payload.quantity;
      } else {
        state.items.push(action.payload);
      }
    },
    removeItem(state, action: PayloadAction<string>) {
      state.items = state.items.filter(i => i.id !== action.payload);
    },
    applyCoupon(state, action: PayloadAction<string>) {
      state.coupon = action.payload;
    },
  },
});

export const { addItem, removeItem, applyCoupon } = cartSlice.actions;
export default cartSlice.reducer;

RTK ক্যোয়ারী: Redux এর ভিতরে সার্ভার স্টেট

RTK RTK ক্যোয়ারী নামে একটি সঙ্গী পাঠায় যা সরাসরি Redux স্টোরের মধ্যে সার্ভারের অবস্থা পরিচালনা করে। এটি এন্ডপয়েন্ট সংজ্ঞা থেকে প্রতিক্রিয়া হুকগুলি স্বয়ংক্রিয়ভাবে তৈরি করে এবং ক্যাশিং, অবৈধকরণ এবং আশাবাদী আপডেটগুলি পরিচালনা করে।

// services/productsApi.ts
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const productsApi = createApi({
  reducerPath: 'productsApi',
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  tagTypes: ['Product'],
  endpoints: (builder) => ({
    getProducts: builder.query<Product[], void>({
      query: () => '/products',
      providesTags: ['Product'],
    }),
    updateProduct: builder.mutation<Product, Partial<Product>>({
      query: ({ id, ...patch }) => ({
        url: `/products/${id}`,
        method: 'PATCH',
        body: patch,
      }),
      invalidatesTags: ['Product'],
    }),
  }),
});

export const { useGetProductsQuery, useUpdateProductMutation } = productsApi;

যখন আপনার Redux DevTools-এর মাধ্যমে টাইম-ট্রাভেল ডিবাগিংয়ের প্রয়োজন হয়, যখন একাধিক দলকে এনফোর্সড কনভেনশন সহ একটি শেয়ার্ড স্টেট মডেলে অবদান রাখতে হয়, অথবা যখন আপনার কাছে জটিল ক্রস-স্লাইস ব্যবসায়িক যুক্তি থাকে যা মিডলওয়্যার থেকে উপকৃত হয় যেমন redux-saga বা redux-observable.

জুস্ট্যান্ড: অনুষ্ঠান ছাড়াই লাইটওয়েট গ্লোবাল স্টেট

জুস্ট্যান্ড একটি আমূল ভিন্ন পদ্ধতি গ্রহণ করে। কোন প্রদানকারী, কোন হ্রাসকারী, এবং কোন কর্মের ধরন নেই। আপনি স্টেট এবং পদ্ধতি সহ একটি প্লেইন জাভাস্ক্রিপ্ট অবজেক্ট হিসাবে একটি স্টোরকে সংজ্ঞায়িত করুন, তারপর এটিকে একটি হুক দিয়ে গ্রাস করুন। পুরো API একটি স্ক্রিনে ফিট করে।

// stores/useCartStore.ts
import { create } from 'zustand';
import { persist, devtools } from 'zustand/middleware';

interface CartStore {
  items: CartItem[];
  addItem: (item: CartItem) => void;
  removeItem: (id: string) => void;
  totalPrice: () => number;
  clear: () => void;
}

export const useCartStore = create<CartStore>()(
  devtools(
    persist(
      (set, get) => ({
        items: [],

        addItem: (item) =>
          set((state) => {
            const existing = state.items.find((i) => i.id === item.id);
            if (existing) {
              return {
                items: state.items.map((i) =>
                  i.id === item.id
                    ? { ...i, quantity: i.quantity + item.quantity }
                    : i
                ),
              };
            }
            return { items: [...state.items, item] };
          }),

        removeItem: (id) =>
          set((state) => ({ items: state.items.filter((i) => i.id !== id) })),

        totalPrice: () =>
          get().items.reduce((sum, i) => sum + i.price * i.quantity, 0),

        clear: () => set({ items: [] }),
      }),
      { name: 'cart-storage' }
    )
  )
);

দানাদার সদস্যতা এবং কর্মক্ষমতা

জুস্ট্যান্ড নির্বাচক-ভিত্তিক সাবস্ক্রিপশনের মাধ্যমে কনটেক্সট-এর রি-রেন্ডার সমস্যা সমাধান করে। একটি কম্পোনেন্ট শুধুমাত্র তখনই রি-রেন্ডার করে যখন এটি নির্বাচিত স্টেটের স্লাইস পরিবর্তিত হয়।

// Only re-renders when items.length changes, not on price changes
const itemCount = useCartStore((state) => state.items.length);

// Only re-renders when the total changes
const total = useCartStore((state) => state.totalPrice());

জুস্ট্যান্ডের মিডলওয়্যার ইকোসিস্টেম অধ্যবসায়কে কভার করে localStorage, DevTools ইন্টিগ্রেশন, Immer-স্টাইল মিউটেশন, এবং URL সিঙ্ক। যে দলগুলি Redux-স্তরের সেটআপ খরচ ছাড়াই Redux-স্তরের ক্ষমতা চায় তাদের জন্য এটি পছন্দের।

জোতাই: পরমাণু রাষ্ট্র রিকোয়েল দ্বারা অনুপ্রাণিত

জোতাই মডেলগুলি পরমাণুর গ্রাফ হিসাবে বর্ণনা করে - রাষ্ট্রের ক্ষুদ্র, সংমিশ্রণযোগ্য একক যা একে অপরের থেকে উদ্ভূত হতে পারে। এই মডেলটি গতিশীল অবস্থার জন্য বিশেষভাবে শক্তিশালী: সম্পাদক নোডের একটি তালিকা ভাবুন যেখানে প্রতিটি নোডের নিজস্ব স্বাধীন নির্বাচন/ফোকাস অবস্থা আছে, অথবা একটি জটিল ফর্ম যেখানে ক্ষেত্রের দৃশ্যমানতা অন্যান্য ক্ষেত্রের মানগুলির উপর নির্ভর করে।

// atoms/filterAtoms.ts
import { atom, selector } from 'jotai';

export const searchTermAtom = atom('');
export const categoryAtom = atom<string | null>(null);
export const productsAtom = atom<Product[]>([]);

// Derived atom — recomputes only when its dependencies change
export const filteredProductsAtom = atom((get) => {
  const products = get(productsAtom);
  const term = get(searchTermAtom).toLowerCase();
  const category = get(categoryAtom);

  return products.filter((p) => {
    const matchesTerm = p.name.toLowerCase().includes(term);
    const matchesCategory = category === null || p.category === category;
    return matchesTerm && matchesCategory;
  });
});
// ProductList.tsx
import { useAtom, useAtomValue } from 'jotai';

function ProductList() {
  const [searchTerm, setSearchTerm] = useAtom(searchTermAtom);
  const filtered = useAtomValue(filteredProductsAtom);

  return (
    <>
      <input value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} />
      {filtered.map((p) => <ProductCard key={p.id} product={p} />)}
    </>
  );
}

জোতাই-এর সূক্ষ্ম-দানাযুক্ত প্রতিক্রিয়াশীল মডেলের অর্থ হল যখন অনুসন্ধান শব্দটি পরিবর্তিত হয়, শুধুমাত্র সেই উপাদানগুলি যা প্রকৃতপক্ষে সদস্যতা নেয় filteredProductsAtom পুনরায় রেন্ডার উপাদান শুধুমাত্র সদস্যতা categoryAtom অস্পৃশ্য এটি জোতাইকে ঘন, পরস্পর নির্ভরশীল স্টেট গ্রাফ সহ অ্যাপ্লিকেশনের জন্য চমৎকার করে তোলে।

TanStack ক্যোয়ারী: সার্ভার স্টেটের জন্য সঠিক হোম

TanStack ক্যোয়ারী (পূর্বে প্রতিক্রিয়া ক্যোয়ারী) একটি সাধারণ রাষ্ট্র পরিচালনার লাইব্রেরি নয় - এটি একটি সার্ভার-স্টেট লাইব্রেরি, এবং এটি ইকোসিস্টেমের অন্য যেকোনো কিছুর চেয়ে সেই দায়িত্বটি ভালভাবে পরিচালনা করে। ট্যানস্ট্যাক ক্যোয়ারী ছাড়া রিঅ্যাক্টে রিমোট ডেটা আনা, ক্যাশ করা, সিঙ্ক্রোনাইজ করা এবং আপডেট করার মানে হল ম্যানুয়ালি লোডিং ফ্ল্যাগ, ত্রুটির বস্তু, এবং ক্যাশে অকার্যকরকরণ স্থানীয় রাজ্য বা বিশ্বব্যাপী স্টোরে পরিচালনা করা। TanStack ক্যোয়ারী যে সব স্বয়ংক্রিয়.

// hooks/useProducts.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';

export function useProducts(filters: ProductFilters) {
  return useQuery({
    queryKey: ['products', filters],
    queryFn: () => api.getProducts(filters),
    staleTime: 5 * 60 * 1000,   // treat data as fresh for 5 minutes
    gcTime: 10 * 60 * 1000,     // keep unused data in cache for 10 minutes
  });
}

export function useUpdateProduct() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (update: ProductUpdate) => api.updateProduct(update),

    // Optimistic update
    onMutate: async (update) => {
      await queryClient.cancelQueries({ queryKey: ['products'] });
      const previous = queryClient.getQueryData(['products']);
      queryClient.setQueryData(['products'], (old: Product[]) =>
        old.map((p) => (p.id === update.id ? { ...p, ...update } : p))
      );
      return { previous };
    },

    onError: (_err, _update, context) => {
      queryClient.setQueryData(['products'], context?.previous);
    },

    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['products'] });
    },
  });
}

কোয়েরি কী অ্যারে হল TanStack কোয়েরির ক্যাশিং আদিম। একই কী শেয়ার করা যেকোনো প্রশ্ন একই ক্যাশে এন্ট্রি শেয়ার করে। আপনি যখন একটি কী বাতিল করেন, তখন সেই কীটিতে সদস্যতা নেওয়া প্রতিটি উপাদান স্বয়ংক্রিয়ভাবে পটভূমিতে পুনরায় আনয়ন করে এবং যখন নতুন ডেটা আসে তখন আপডেট হয়।

Next.js-এ প্রিফেচিং এবং হাইড্রেশন

একটি Next.js অ্যাপ্লিকেশানে আপনি সার্ভারে প্রশ্নগুলি প্রিফেচ করতে পারেন এবং প্রাথমিক পৃষ্ঠার রেন্ডারের জন্য লোডিং স্পিনারগুলিকে সম্পূর্ণরূপে বাদ দিয়ে HTML পেলোডে সেগুলিকে ডিহাইড্রেট করতে পারেন৷

// app/products/page.tsx (Next.js App Router)
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query';

export default async function ProductsPage() {
  const queryClient = new QueryClient();
  await queryClient.prefetchQuery({
    queryKey: ['products', {}],
    queryFn: () => api.getProducts({}),
  });

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      <ProductList />
    </HydrationBoundary>
  );
}

গ্রন্থাগারের সমন্বয়: একটি ব্যবহারিক আর্কিটেকচার

বাস্তব অ্যাপ্লিকেশনগুলি প্রায় সবসময়ই একাধিক সরঞ্জাম একত্রিত করে উপকৃত হয়, প্রতিটি রাষ্ট্রের নিজস্ব বিভাগের জন্য দায়ী। একটি সুগঠিত মাঝামাঝি থেকে বৃহৎ প্রতিক্রিয়া অ্যাপ্লিকেশন এইরকম দেখতে পারে:

  • TanStack ক্যোয়ারী সমস্ত সার্ভার অবস্থার মালিক। এটি দূরবর্তী ডেটা নিয়ে আসে, ক্যাশে করে এবং সিঙ্ক্রোনাইজ করে। আর কিছুই API প্রতিক্রিয়া স্পর্শ করে না।
  • জুস্ট্যান্ড বিশ্বব্যাপী ক্লায়েন্ট রাষ্ট্রের মালিক - শপিং কার্ট, প্রমাণীকৃত ব্যবহারকারীর সেশন, UI পছন্দসমূহ, এবং যেকোন ক্রস-ফিচার সমন্বয় যা প্রসঙ্গটির জন্য অত্যন্ত জটিল।
  • প্রসঙ্গ প্রতিক্রিয়া নিম্ন-মন্থন কনফিগারেশনের মালিক - বর্তমান থিম, লোকেল, বৈশিষ্ট্য পতাকা।
  • useState / useReducer নিজস্ব স্থানীয় উপাদান অবস্থা — মডেল খোলা/বন্ধ, ফর্ম ক্ষেত্রের মান (বা জটিল ফর্মের জন্য প্রতিক্রিয়া হুক ফর্ম), ট্যাব নির্বাচন।
  • ইউআরএল অনুসন্ধান প্যারাম নিজস্ব ন্যাভিগেশনাল অবস্থা — সক্রিয় ফিল্টার, সাজানোর ক্রম, বর্তমান পৃষ্ঠা নম্বর।

উদ্বেগের এই বিচ্ছেদ শুধু নান্দনিক নয়। এর মানে হল আপনার সার্ভার-স্টেট ক্যাশে কখনই UI স্টেটের সাথে দূষিত হয় না, আপনার গ্লোবাল ক্লায়েন্ট স্টোর কখনই প্রতিক্রিয়া ডেটা সহ বেলুন করে না যা TanStack ক্যোয়ারী আরও দক্ষতার সাথে ক্যাশে করবে এবং আপনার প্রসঙ্গ কখনই অ্যাপ-ওয়াইড রি-রেন্ডারকে ট্রিগার করে না কারণ কেউ এতে দ্রুত পরিবর্তনশীল মান সঞ্চয় করে।

কর্মক্ষমতা নিদর্শন জানা মূল্য

পুনঃনির্বাচন সহ স্মরণীয় নির্বাচক

একটি Redux স্টোর থেকে গণনা করা মান প্রাপ্ত করার সময়, প্রতিটি রেন্ডারে পুনরায় গণনা এড়াতে পুনরায় নির্বাচন ব্যবহার করুন। RTK পুনরায় রপ্তানি করে createSelector রিসিলেক্ট থেকে।

import { createSelector } from '@reduxjs/toolkit';

const selectItems = (state: RootState) => state.cart.items;

export const selectCartSummary = createSelector(selectItems, (items) => ({
  count: items.reduce((n, i) => n + i.quantity, 0),
  total: items.reduce((sum, i) => sum + i.price * i.quantity, 0),
}));

ইউজ ট্রানজিশন সহ রেন্ডারকে বিভক্ত করা

18 এর প্রতিক্রিয়া useTransition আপনাকে একটি রাষ্ট্রীয় আপডেটকে অ-জরুরী হিসাবে চিহ্নিত করতে দেয় যাতে ব্রাউজার এটিকে ব্যবহারকারীর ইনপুটের মতো উচ্চ-অগ্রাধিকার কাজ পরিচালনা করতে বাধা দিতে পারে। এটি বিশেষভাবে কার্যকর যখন একটি রাষ্ট্র পরিবর্তন একটি ব্যয়বহুল পুনরায় রেন্ডার ট্রিগার করে।

const [isPending, startTransition] = useTransition();

const handleFilterChange = (value: string) => {
  startTransition(() => {
    setFilterValue(value); // expensive downstream re-render is deferrable
  });
};

অবজেক্ট আইডেন্টিটি ইস্যু এড়িয়ে চলা

ফ্যান্টম রি-রেন্ডারের একটি সাধারণ উৎস হল রেন্ডারের ভিতরে নতুন অবজেক্ট বা অ্যারে লিটারেল তৈরি করা। useMemo এবং useCallback এখানে আপনার সরঞ্জামগুলি আছে, কিন্তু শুধুমাত্র তখনই প্রয়োগ করুন যখন আপনার কাছে কর্মক্ষমতা সমস্যার প্রমাণ থাকে — অকাল মেমোইজেশন নিশ্চিত সুবিধা ছাড়াই জ্ঞানীয় ওভারহেড যোগ করে।

ডিসিশন ফ্রেমওয়ার্ক

একটি নতুন বৈশিষ্ট্যের জন্য একটি রাষ্ট্র পরিচালনা পদ্ধতি নির্বাচন করার সময় নিম্নলিখিত সিদ্ধান্ত গাছ ব্যবহার করুন:

  1. রাষ্ট্র কি একটি উপাদান বা একটি ছোট উপবৃক্ষের জন্য বিশুদ্ধভাবে স্থানীয়? ব্যবহার করুন useState বা useReducer.
  2. রাষ্ট্র কি একটি সার্ভার থেকে আনা ডেটা প্রতিনিধিত্ব করে? ব্যবহার করুন TanStack ক্যোয়ারী.
  3. এটা কি বিশ্বব্যাপী ক্লায়েন্ট রাষ্ট্র যে গাছ জুড়ে অনেক উপাদান প্রয়োজন? জন্য পৌঁছান জুস্ট্যান্ড যদি না আপনি ইতিমধ্যেই একটি Redux কোডবেসে থাকেন।
  4. রাষ্ট্র কি খুব কমই পরিবর্তিত হয় এবং একটি কনফিগারেশন উদ্দেশ্য (থিম, লোকেল) পরিবেশন করে? ব্যবহার করুন প্রসঙ্গ প্রতিক্রিয়া.
  5. রাষ্ট্র কি অনেক প্রাপ্ত মানগুলির সাথে অত্যন্ত আন্তঃসংযুক্ত? বিবেচনা করুন জোতাই.
  6. আপনার কি টাইম-ট্রাভেল ডিবাগিং, কঠোর আর্কিটেকচারাল কনভেনশন বা জটিল অ্যাসিঙ্ক সাগাস দরকার? ব্যবহার করুন Redux টুলকিট.

এড়ানোর জন্য সাধারণ অ্যান্টি-প্যাটার্নস

  • Redux বা Zustand এ সার্ভারের প্রতিক্রিয়া সংরক্ষণ করা। TanStack ক্যোয়ারী সেই ডেটার মালিক হতে দিন। এটি একটি বিশ্বব্যাপী দোকানে নকল করা সিঙ্ক্রোনাইজেশন বাগ তৈরি করে।
  • একটি একক বৃহদায়তন দোকান সবকিছু colocating. একই স্লাইসের অন্তর্গত সম্পর্কহীন অবস্থা অপ্রয়োজনীয় সংযোগকে জোর করে এবং পরীক্ষাকে কঠিন করে তোলে।
  • উচ্চ-ফ্রিকোয়েন্সি আপডেটের জন্য প্রসঙ্গ ব্যবহার করা। প্রতিটি প্রসঙ্গ মান পরিবর্তন সমস্ত ভোক্তাদের পুনরায় রেন্ডার করে। প্রতিটি কীস্ট্রোক বা অ্যানিমেশন ফ্রেমে পরিবর্তন হওয়া মানগুলির জন্য, প্রসঙ্গটি ভুল টুল।
  • উপাদান ভিতরে প্রাপ্ত অবস্থা. কম্পিউটেড মানগুলি যেগুলি রাজ্যের উপর নির্ভর করে সেগুলিকে স্মরণ করা উচিত নির্বাচক বা প্রাপ্ত পরমাণু, প্রতিটি রেন্ডারে চলা ইনলাইন গণনা নয়।
  • লোডিং এবং ত্রুটির অবস্থা উপেক্ষা করা। সার্ভারের অবস্থা সহজাতভাবে অ্যাসিঙ্ক্রোনাস। TanStack ক্যোয়ারী পৃষ্ঠতল isLoading, isError, এবং error প্রতিটি প্রশ্নের জন্য; তাদের ব্যবহার করুন

উপসংহার

প্রতিক্রিয়ায় রাষ্ট্র পরিচালনার ল্যান্ডস্কেপ কখনই স্বাস্থ্যকর ছিল না। আপনাকে আর ভারী ফ্রেমওয়ার্ক এবং স্ক্র্যাচ থেকে সবকিছু তৈরি করার মধ্যে বেছে নিতে হবে না। Redux Toolkit তার পূর্বসূরীর বয়লারপ্লেট ছাড়া এন্টারপ্রাইজ-গ্রেডের পূর্বাভাস প্রদান করে। জুস্ট্যান্ড সেটআপের একটি ভগ্নাংশের সাথে একই শক্তি নিয়ে আসে। জোতাই সূক্ষ্ম দানাদার, গতিশীল অবস্থার গ্রাফে কঠিন সমস্যার সমাধান করে। এবং ট্যানস্ট্যাক ক্যোয়ারী সার্ভারের অবস্থা নিশ্চিতভাবে সমাধান করেছে - যদি আপনি এখনও API প্রতিক্রিয়া পরিচালনা করেন useEffect এবং useState, মাইগ্রেট করার জন্য আপনি নিজের কাছে ঋণী।

সবচেয়ে গুরুত্বপূর্ণ অন্তর্দৃষ্টি হল শ্রেণীবদ্ধ: প্রথমে আপনি কোন ধরনের রাষ্ট্রের সাথে কাজ করছেন তা চিহ্নিত করুন, তারপর সেই বিভাগের জন্য অপ্টিমাইজ করা টুলটি নির্বাচন করুন। সবকিছুকে একটি সিস্টেমে ফানেল করার প্রবৃত্তিকে প্রতিরোধ করুন। একটি স্তরযুক্ত পদ্ধতি — সার্ভার স্টেটের জন্য ট্যানস্ট্যাক ক্যোয়ারী, গ্লোবাল ক্লায়েন্ট স্টেটের জন্য জুস্ট্যান্ড, কনফিগারেশনের জন্য প্রসঙ্গ এবং অন্য সব কিছুর জন্য স্থানীয় রাজ্য — এমন কোডবেস তৈরি করে যেগুলি সম্পর্কে যুক্তি দেওয়া সহজ, পরীক্ষা করা সহজ এবং দল এবং প্রয়োজনীয়তা বৃদ্ধির সাথে সাথে আরও বেশি রক্ষণাবেক্ষণযোগ্য।