من غيرها، جلب قائمة طلاب بيتكتب كده غالبًا: تلات حالات، و useEffect بيعمل fetch مرة واحدة.
students-before.jsx
const [data, setData] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => { fetch("/api/students") .then((res) => res.json()) .then(setData) .catch(setError) .finally(() => setLoading(false));}, []);الطلب نجح، بس أنت اللي ماسك كل حاجة بإيدك. مفيش كاش. مفيش إعادة جلب لوحدها. لو طلبين سبقوا بعض، الآخر ممكن يوصل الأول والنتيجة تتلخبط. ولو صفحتين محتاجين نفس القائمة، الطلب يتكرر.
TanStack Query بتمسك حالة السيرفر: الكاش، والإعادة، ومشاركة نفس الطلب. الاسم التاني الشائع React Query. دي مش راوتر.
الإعداد
الأوامر بتتغير مع الإصدار. راجع الدوكس قبل النسخ.
terminal
npm install @tanstack/react-querynpm install -D @tanstack/react-query-devtoolsQueryClient هو صاحب الكاش في التطبيق كله. اعمله مرة بره الكومبوننت، عشان الرسم الجديد ما يمسحش المخزن.
main.tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";import { ReactQueryDevtools } from "@tanstack/react-query-devtools";const queryClient = new QueryClient();function App() { return ( <QueryClientProvider client={queryClient}> <YourApp /> <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider> );}أي useQuery تحت الـ Provider بيشوف نفس المخزن. أدوات التطوير تقعد مقفولة لحد ما تفتحها، وبتوريك المفاتيح والداتا وهي بتتحدث.
خلّصت الفصل لما
🧠 اختبر نفسك
١) المكتبة دي بتحل أنهي نوع حالة؟
حالة السيرفر: الداتا الجاية من الـ API، مش عنوان الصفحة.
٢) ليه QueryClient مش جوه App؟
عشان الكاش ما يتخلقش من جديد كل رسم ويمسح اللي اتخزّن.
٣) صفحتين طلبوا نفس الطلاب من غير المكتبة. إيه اللي بيحصل؟
طلبين منفصلين. المكتبة بتخلّيهم يشتركوا في نفس المفتاح ونفس الجلب.