TanStack Query في 2026: ما الذي لم تستبدله مكوّنات الخادم
جدول المحتويات
عن الكاتب

Ahmed Mahmoud
كاتب ومطوّر
مهندس برمجيات شغوف بتطوير الويب وتصميم تجربة المستخدم.
مؤسّس ديفيا · eng-ahmed.com ↗RSC غيّر الوضع الافتراضي لا المهمة كلها
حين نضجت مكوّنات الخادم في React وإجراءات الخادم، شاع القول بأن مكتبات جلب البيانات في العميل لم تعد ضرورية. بعد عامين من إطلاق تطبيقات App Router في Devya وجدنا هذا صحيحًا نصفيًا: مكوّنات الخادم استبدلت الجلب الافتراضي لا المهمة بأكملها. هنا نوضّح متى ما زلنا نستخدم TanStack Query ومتى أزلناها.
ما الذي استبدلته مكوّنات الخادم والإجراءات فعليًا
لبيانات الصفحة الأولية، فإن مكوّن خادم ينتظر قاعدة البيانات أو واجهة برمجية أبسط من أي مكتبة عميل: لا حالة تحميل، ولا سلسلة طلبات من جهة العميل، ولا شيفرة تسلسل زائدة، ولا تتحوّل البيانات إلى JSON يعيد المتصفح تحليله. ولعمليات الإنشاء والتعديل والحذف المباشرة، يغطّي إجراء خادم مع revalidatePath الدورة كاملة دون خطاف تعديل أو مفتاح استعلام. وحين يكون التطبيق في معظمه نماذج وقراءات على مستوى الصفحة، نطلقه دون ذاكرة تخزين في العميل، فيكون أصغر وأسهل في الفهم، وقد أزلنا المكتبة من مشاريع تناسب هذا الشكل دون أن نفتقدها.
```tsx // app/dashboard/page.tsx — بدون أي مكتبة عميل export default async function Dashboard() { const projects = await db.query.projects.findMany(); return <ProjectList projects={projects} />; } ```
أين تظل ذاكرة العميل ضرورية
كل حالة أبقينا فيها على TanStack Query تشترك في صفة واحدة: البيانات تتغيّر وفق توقيت العميل لا توقيت الطلب. مكوّنات الخادم تُصيَّر مرة واحدة لكل طلب. وحين تحتاج الواجهة إلى الاستقصاء الدوري أو إعادة الجلب أو التقسيم إلى صفحات أو مشاركة ذاكرة مؤقتة عبر المسارات دون تنقّل كامل، تصبح ذاكرة العميل هي الأداة الصحيحة. فالعناصر شبه اللحظية تحتاج إلى فاصل إعادة جلب لا مقابل له في مكوّنات الخادم، والتمرير اللانهائي يستفيد من useInfiniteQuery في إدارة المؤشرات وإزالة تكرار الطلبات الجارية، والبيانات التي تقرؤها عدة مسارات — المستخدم الحالي أو إعدادات المؤسسة — تُخدَم فورًا من ذاكرة مشتركة عند التنقّل. وعندما ينبغي لتعديل واحد أن يحدّث تفاؤليًا قائمة وعدّادًا وشارة في الترويسة معًا، فالذاكرة المشتركة أنظف من ربط عدة حالات تفاؤلية منفصلة.
النمط الذي يجعلهما يتعايشان: الترطيب
الخطأ المبكر هو التعامل مع الأمر كخيار أحادي. أقوى إعداد يستخدم الاثنين معًا: نجلب على الخادم ثم نسلّم النتيجة إلى TanStack Query كي تبدأ ذاكرة العميل دافئة ويخلو أول تصيير من حالة التحميل. نجهّز مسبقًا مفتاح الاستعلام نفسه على الخادم، ونجفّفه، ونلفّ شجرة العميل بـ HydrationBoundary. يقرأ العميل المفتاح ذاته فيُصيَّر فورًا من الذاكرة المُرطَّبة، ثم يتولّى تحديث الحداثة بعدها.
```tsx // مكوّن خادم const qc = new QueryClient(); await qc.prefetchQuery({ queryKey: ['projects'], queryFn: () => db.query.projects.findMany() }); return ( <HydrationBoundary state={dehydrate(qc)}> <ProjectsClient /> </HydrationBoundary> ); ```
التعديلات: revalidatePath مقابل invalidateQueries
هذا أكثر ما يثير الالتباس في المراجعة. كلاهما يبطل ذاكرة لكن ذاكرتين مختلفتين. يطلب revalidatePath من Next.js إعادة تصيير مكوّنات الخادم لمسار ما، بينما يطلب invalidateQueries من TanStack Query إعادة جلب استعلام عميل. فإن كانت القيمة في ذاكرة العميل، فإن إجراء خادم يستدعي revalidatePath وحده لن يمسّها. قاعدتنا أن نسند مالكًا واحدًا لكل قطعة بيانات: إن قُرئت القيمة عبر useQuery، فعلى التعديل الذي يغيّرها أن يُبطل ذلك الاستعلام بدل الاعتماد على revalidatePath ليبقي ذاكرة العميل صادقة.
قاعدتنا في القرار حاليًا
ابدأ من دونها. صيّر القراءات في مكوّنات الخادم، واكتب عبر إجراءات الخادم، ولا تضف TanStack Query إلا عند ظهور حاجة ملموسة: استقصاء دوري، أو تمرير لانهائي، أو ذاكرة عميل مشتركة عبر المسارات، أو تحديثات تفاؤلية تمتد عبر عدة مكوّنات. إضافتها لاحقًا تغيير صغير محلي، أما إزالة ذاكرة لم يحتجها التطبيق فليست كذلك. صيغ النقاش قبل عامين على أنه مكوّنات الخادم في مقابل جلب العميل، لكنهما في الحقيقة يجيبان عن سؤالين مختلفين: أحدهما يملك التصيير الأول على الخادم، والآخر يملك حداثة توقيت العميل. والتطبيقات التي نرضى عنها أكثر تستعمل كلًّا منهما فيما يُتقنه.
قراءات إضافية
هندسة الواجهات الأمامية
ترحيل المشاريع من Edge Runtime في Vercel: ملاحظات ميدانية
بيئة Edge Runtime في Vercel أصبحت قيد الإيقاف التدريجي لصالح Node.js على Fluid Compute — إليكم ما وجدناه أثناء ترحيل مسارات Next.js، ولماذا استمر البث بالعمل دون أي تغيير.
هندسة الواجهات الأمامية
معالجات المسارات مقابل إجراءات الخادم في Next.js: متى نستخدم كلًّا منهما
كلٌّ من إجراءات الخادم ومعالجات المسارات ينفّذ كودًا على الخادم في موجّه تطبيقات Next.js، لكنهما يحلّان مشكلتين مختلفتين. في ديفيا نستخدم إجراءات الخادم لعمليات التعديل القادمة من واجهتنا، ومعالجات المسارات لواجهات البرمجة العامة وخطافات الويب والبث.