राज्य प्रबंधन प्रत्येक गैर-तुच्छ रिएक्ट एप्लिकेशन के केंद्र में होता है। इसे ठीक से प्राप्त करें और आपका कोडबेस शानदार ढंग से स्केल हो जाएगा; इसे गलत समझें और आप प्रोप-ड्रिलिंग बुरे सपने, पुराने यूआई और खुद को गुमनामी में फिर से प्रस्तुत करने वाले घटकों के साथ समाप्त हो जाएंगे। अच्छी खबर यह है कि रिएक्ट पारिस्थितिकी तंत्र नाटकीय रूप से परिपक्व हो गया है। अब आपके पास उद्देश्य-निर्मित टूल का एक समृद्ध मेनू है - रेडक्स टूलकिट, ज़स्टैंड, जोटाई, टैनस्टैक क्वेरी, और अंतर्निहित संदर्भ API - प्रत्येक समस्या के एक विशिष्ट वर्ग के लिए अनुकूलित है।
यह आलेख प्रत्येक समाधान के बारे में गहराई से बताता है, ठोस उदाहरणों के साथ ट्रेड-ऑफ़ की व्याख्या करता है, और आपको एक निर्णय रूपरेखा देता है जिसे आप तुरंत अपनी परियोजनाओं पर लागू कर सकते हैं।
राज्य के विभिन्न प्रकारों को समझना
किसी भी लाइब्रेरी तक पहुंचने से पहले, यह स्पष्ट होना जरूरी है कि आप वास्तव में किस प्रकार की स्थिति का प्रबंधन कर रहे हैं। विभिन्न राज्य श्रेणियों को मिलाना अधिकांश अति-इंजीनियर्ड रिएक्ट अनुप्रयोगों का मूल कारण है।
- स्थानीय यूआई स्थिति - क्या ड्रॉपडाउन खुला है, कौन सा टैब सक्रिय है, नियंत्रित इनपुट का वर्तमान मूल्य। यह राज्य एक घटक या एक छोटे उपवृक्ष के स्वामित्व में है।
- साझा ग्राहक स्थिति - डेटा जिसे एकाधिक, संभावित रूप से दूर के घटकों को पढ़ने या लिखने की आवश्यकता होती है: वर्तमान में प्रमाणित उपयोगकर्ता, थीम प्राथमिकताएं, एक शॉपिंग कार्ट।
- सर्वर स्थिति - जो डेटा सर्वर पर उत्पन्न होता है, वह स्वभाव से अतुल्यकालिक होता है, और उसे कैश अमान्यकरण, पृष्ठभूमि पुनः प्राप्त करने और लोडिंग/त्रुटि जीवनचक्र प्रबंधन की आवश्यकता होती है।
- यूआरएल स्थिति - फ़िल्टर, पेजिनेशन, और खोज शब्द जो एक पेज रीफ्रेश से बचे रहने चाहिए और एक लिंक के माध्यम से साझा किए जाने योग्य होने चाहिए।
- रूप अवस्था - नियंत्रित इनपुट, सत्यापन त्रुटियां और सबमिशन स्थिति, अक्सर रिएक्ट हुक फॉर्म जैसी समर्पित लाइब्रेरी द्वारा सबसे अच्छी तरह से नियंत्रित की जाती है।
सबसे प्रभावशाली चीज़ जो आप कर सकते हैं वह है राज्य की हर श्रेणी को एक वैश्विक स्टोर में डालने की इच्छा का विरोध करना। प्रत्येक श्रेणी की अलग-अलग स्थिरता आवश्यकताएँ, अलग-अलग जीवनकाल और अलग-अलग अद्यतन आवृत्तियाँ होती हैं।
प्रतिक्रिया संदर्भ: अंतर्निहित विकल्प
कॉन्टेक्स्ट 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;
}
संदर्भ प्रदर्शन जाल
संदर्भ में एक प्रसिद्ध प्रदर्शन विशेषता है जो कई डेवलपर्स को परेशान करती है: जब भी संदर्भ मूल्य संदर्भ बदलता है तो प्रत्येक उपभोक्ता पुन: प्रस्तुत करता है। यदि आप एक बड़ी, बार-बार परिवर्तित होने वाली वस्तु को एक ही संदर्भ में संग्रहीत करते हैं, तो आप अपने पूरे पेड़ में अनावश्यक पुन: प्रस्तुतीकरण को ट्रिगर करेंगे।
शमन रणनीतियाँ हैं:
- अद्यतन आवृत्ति के आधार पर संदर्भों को विभाजित करें। उपयोगकर्ता ऑब्जेक्ट को एक संदर्भ में और यूआई प्राथमिकताओं को दूसरे संदर्भ में रखें।
- मूल्य वस्तु को याद रखें
useMemoइसलिए संदर्भ केवल तभी बदलता है जब डेटा वास्तव में बदलता है। - उपयोग
React.memoउपभोक्ता घटकों पर पुन: रेंडरर्स को छोड़ने के लिए जब वे जिन प्रॉप्स की परवाह करते हैं वे नहीं बदले हैं।
ईमानदार निष्कर्ष यह है कि कॉन्टेक्स्ट कम आवृत्ति वाली वैश्विक स्थिति के लिए उत्कृष्ट है, लेकिन यह सामान्य प्रयोजन वाला राज्य प्रबंधन समाधान नहीं है। एक बार जब आप खुद को कॉन्टेक्स्ट के री-रेंडर व्यवहार के आसपास काम करने के लिए विस्तृत संस्मरण लिखते हुए पाते हैं, तो यह एक समर्पित पुस्तकालय तक पहुंचने का समय है।
Redux टूलकिट: परिपक्व उद्यम विकल्प
रेडक्स की बॉयलरप्लेट के लिए प्रतिष्ठा है - यह प्रतिष्ठा उसने टूलकिट से पहले के युग में अर्जित की थी। Redux टूलकिट (RTK) उस समारोह को समाप्त कर देता है जो Redux को शक्तिशाली बनाता है: सख्त यूनिडायरेक्शनल डेटा प्रवाह के साथ एक एकल, पूर्वानुमानित, निरीक्षण योग्य राज्य वृक्ष।
आरटीके जहाज 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 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 टूलकिट सही विकल्प है 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 अछूते हैं. यह जोताई को सघन, अन्योन्याश्रित राज्य ग्राफ़ वाले अनुप्रयोगों के लिए उत्कृष्ट बनाता है।
टैनस्टैक क्वेरी: सर्वर स्थिति के लिए सही घर
टैनस्टैक क्वेरी (पूर्व में रिएक्ट क्वेरी) एक सामान्य राज्य प्रबंधन लाइब्रेरी नहीं है - यह एक सर्वर-स्टेट लाइब्रेरी है, और यह पारिस्थितिकी तंत्र में किसी भी अन्य चीज़ की तुलना में उस जिम्मेदारी को बेहतर ढंग से संभालती है। टैनस्टैक क्वेरी के बिना रिएक्ट में रिमोट डेटा को लाने, कैशिंग, सिंक्रोनाइज़ करने और अपडेट करने का मतलब आमतौर पर स्थानीय स्थिति या वैश्विक स्टोर में लोडिंग फ़्लैग, त्रुटि ऑब्जेक्ट और कैश अमान्यता को मैन्युअल रूप से प्रबंधित करना है। टैनस्टैक क्वेरी उन सभी को स्वचालित करती है।
// 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'] });
},
});
}
क्वेरी कुंजी सरणी टैनस्टैक क्वेरी का कैशिंग आदिम है। समान कुंजी साझा करने वाली कोई भी क्वेरी समान कैश प्रविष्टि साझा करती है। जब आप किसी कुंजी को अमान्य करते हैं, तो उस कुंजी से सब्सक्राइब किया गया प्रत्येक घटक स्वचालित रूप से पृष्ठभूमि में पुनः प्राप्त हो जाता है और नया डेटा आने पर अपडेट हो जाता है।
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>
);
}
पुस्तकालयों का संयोजन: एक व्यावहारिक वास्तुकला
वास्तविक एप्लिकेशन लगभग हमेशा कई उपकरणों के संयोजन से लाभान्वित होते हैं, जिनमें से प्रत्येक राज्य की अपनी श्रेणी के लिए जिम्मेदार होता है। एक अच्छी तरह से संरचित मध्य से बड़े रिएक्ट एप्लिकेशन इस तरह दिख सकता है:
- टैनस्टैक क्वेरी सभी सर्वर स्थिति का स्वामी है। यह दूरस्थ डेटा को लाता है, कैश करता है और सिंक्रनाइज़ करता है। API प्रतिक्रियाओं को और कुछ नहीं छूता।
- ज़स्टैंड वैश्विक ग्राहक स्थिति का मालिक है - शॉपिंग कार्ट, प्रमाणित उपयोगकर्ता सत्र, यूआई प्राथमिकताएं, और कोई भी क्रॉस-फीचर समन्वय जो संदर्भ के लिए बहुत जटिल है।
- प्रतिक्रिया प्रसंग निम्न-मंथन कॉन्फ़िगरेशन का स्वामी है - वर्तमान विषय, स्थान, फ़ीचर फ़्लैग।
- यूज़स्टेट / यूज़रेड्यूसर स्वयं की स्थानीय घटक स्थिति - मोडल खुला/बंद, फॉर्म फ़ील्ड मान (या जटिल रूपों के लिए रिएक्ट हुक फॉर्म), टैब चयन।
- यूआरएल खोज पैरामीटर स्वयं की नेविगेशनल स्थिति - सक्रिय फ़िल्टर, सॉर्ट क्रम, वर्तमान पृष्ठ संख्या।
सरोकारों का यह पृथक्करण केवल सौन्दर्यपरक नहीं है। इसका मतलब है कि आपका सर्वर-स्टेट कैश कभी भी यूआई स्थिति से प्रदूषित नहीं होता है, आपका वैश्विक क्लाइंट स्टोर कभी भी प्रतिक्रिया डेटा से भरा नहीं होता है जिसे टैनस्टैक क्वेरी अधिक कुशलता से कैश करेगी, और आपका संदर्भ कभी भी ऐप-वाइड री-रेंडर को ट्रिगर नहीं करता है क्योंकि किसी ने इसमें तेजी से बदलते मूल्य को संग्रहीत किया है।
प्रदर्शन पैटर्न जानने लायक
पुनर्चयन के साथ मेमोइज्ड चयनकर्ता
Redux स्टोर से परिकलित मान प्राप्त करते समय, प्रत्येक रेंडर पर पुनः गणना से बचने के लिए Reselect का उपयोग करें। आरटीके पुनः निर्यात करता है 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 यहां आपके उपकरण हैं, लेकिन उन्हें केवल तभी लागू करें जब आपके पास प्रदर्शन समस्या का सबूत हो - समय से पहले याद रखने से गारंटीकृत लाभ के बिना संज्ञानात्मक ओवरहेड जुड़ जाता है।
निर्णय रूपरेखा
किसी नई सुविधा के लिए राज्य प्रबंधन दृष्टिकोण चुनते समय निम्नलिखित निर्णय वृक्ष का उपयोग करें:
- क्या राज्य पूरी तरह से एक घटक या एक छोटे उपवृक्ष के लिए स्थानीय है? उपयोग
useStateयाuseReducer. - क्या राज्य सर्वर से प्राप्त डेटा का प्रतिनिधित्व करता है? उपयोग टैनस्टैक क्वेरी.
- क्या यह वैश्विक ग्राहक स्थिति है जिसकी पेड़ के कई घटकों को आवश्यकता है? के लिए पहुंचें ज़स्टैंड जब तक कि आप पहले से ही Redux कोडबेस में न हों।
- क्या स्थिति शायद ही कभी बदलती है और कॉन्फ़िगरेशन उद्देश्य (थीम, लोकेल) को पूरा करती है? उपयोग प्रतिक्रिया प्रसंग.
- क्या राज्य कई व्युत्पन्न मूल्यों से अत्यधिक जुड़ा हुआ है? विचार करना जोताई.
- क्या आपको समय-यात्रा डिबगिंग, सख्त वास्तुशिल्प सम्मेलनों, या जटिल एसिंक सागा की आवश्यकता है? उपयोग रिडक्स टूलकिट.
बचने के लिए सामान्य विरोधी पैटर्न
- सर्वर प्रतिक्रियाओं को Redux या Zustand में संग्रहीत करना। टैनस्टैक क्वेरी को उस डेटा का स्वामी होने दें। इसे वैश्विक स्टोर में डुप्लिकेट करने से सिंक्रोनाइज़ेशन बग पैदा होते हैं।
- हर चीज़ को एक ही विशाल स्टोर में व्यवस्थित करना। एक ही स्लाइस में असंबंधित स्थिति अनावश्यक युग्मन को मजबूर करती है और परीक्षण को कठिन बना देती है।
- उच्च-आवृत्ति अपडेट के लिए संदर्भ का उपयोग करना। प्रत्येक संदर्भ मूल्य परिवर्तन सभी उपभोक्ताओं को पुनः प्रस्तुत करता है। प्रत्येक कीस्ट्रोक या एनीमेशन फ्रेम पर बदलने वाले मानों के लिए, कॉन्टेक्स्ट गलत टूल है।
- घटकों के अंदर स्थिति प्राप्त करना। गणना किए गए मान जो स्थिति पर निर्भर करते हैं, उन्हें याद किए गए चयनकर्ता या व्युत्पन्न परमाणु होने चाहिए, न कि इनलाइन गणना जो हर रेंडर पर चलती हैं।
- लोडिंग और त्रुटि स्थिति को अनदेखा करना. सर्वर स्थिति स्वाभाविक रूप से अतुल्यकालिक है। टैनस्टैक क्वेरी सतहें
isLoading,isError, औरerrorप्रत्येक प्रश्न के लिए; उनका उपयोग करें।
निष्कर्ष
रिएक्ट में राज्य प्रबंधन परिदृश्य कभी इतना स्वस्थ नहीं रहा। अब आपको भारी ढाँचे और सब कुछ नए सिरे से बनाने के बीच चयन करने की आवश्यकता नहीं है। Redux टूलकिट अपने पूर्ववर्ती के बॉयलरप्लेट के बिना एंटरप्राइज़-ग्रेड पूर्वानुमान प्रदान करता है। ज़स्टैंड सेटअप के एक अंश के साथ वही शक्ति लाता है। जोताई सूक्ष्म, गतिशील स्थिति ग्राफ़ में कठिन समस्याओं को हल करता है। और टैनस्टैक क्वेरी ने सर्वर स्थिति को निश्चित रूप से हल कर दिया है - यदि आप अभी भी API प्रतिक्रियाओं का प्रबंधन कर रहे हैं useEffect और useState, आप पर प्रवास करने का दायित्व है।
The most important insight is categorical: identify what kind of state you are dealing with first, then select the tool optimised for that category. Resist the instinct to funnel everything into one system. A layered approach — TanStack Query for server state, Zustand for global client state, Context for configuration, and local state for everything else — produces codebases that are easier to reason about, easier to test, and far more maintainable as teams and requirements grow.