دورة TanStack Router الكاملة › دورة TanStack Router الكاملة 1 / 1 السابق التالي

السياق (Context)

الدرس 18 من 34 · دورة TanStack Router الكاملة · 6 دقيقة و34 ثانية

الفيديو الأصلي باللغة الإنجليزية. إذا تعذّر تشغيله هنا، شاهده على موقع المؤلف. التفريغ النصي العربي الكامل أدناه.

مستودع الكود لهذا الدرس

الفرع: context-1

[00:02] فكرة السياق (context). إنّها بطريقةٍ ما شبيهة بسياق React الذي قد تكون مألوفًا به، غير أنّهما شيئان مختلفان، ويمكن في الواقع استخدامهما معًا. إذًا في TanStack Router، في أيّ عقدة (node) من شجرة مساراتنا، يمكننا تعريف

[00:17] بعض السياق. فلنقل أنّه في مسار الجذر (root route)، عند تهيئة موجّهنا (router)، نمرّر بعض السياق، وهذا يمكن أن يكون مجرّد بيانات أو حالة (state)، ويمكن أن يكون دالّة (function) أو أيّ شيء، وعندما نُعرِّفه هنا في الجذر فسَيَكُون متاحًا لـ

[00:31] جميع مساراتنا. يمكننا الوصول إليه في مكوّن (component) أيّ مسار أو في أيّ دالّة تحميل (load function)، وبالطبع سَنُلقي نظرة أيضًا على دوالّ التحميل في قسمٍ قادم. إذًا يمكن أن يكون هذا مفيدًا لمشاركة البيانات عبر

[00:43] مسارات متعدّدة. ويمكننا أيضًا تمرير دوالّ، مثل دوالّ جلب البيانات (data fetching) ربّما، أو يمكننا ربّما تهيئة عميل (client) في الجذر ثم تمرير هذا العميل في كلّ مكان، كي يُستخدَم دون الحاجة إلى استيراد (import) وتصدير (export)

[00:55] أشياء. ويمكننا أيضًا ربّما استخدامه لمعلومات المصادقة (authentication)، حيث يكون لَدَينا في الجذر ربما موفّر مصادقة (authentication provider) ما يزوّدنا بمعلومات عن المستخدم (user)، وعن كون المستخدم في وضع تسجيل الدخول (logged in) وما إلى ذلك، ونحن

[01:07] نحتاج إلى الوصول إلى ذلك في كلّ مكان، كي نتمكّن ربّما من حماية بعض المسارات، وعندها يمكننا استخدام هذا السياق. ويمكننا أيضًا استخدامه لأمور أخرى، مثل مسار التنقّل المُختصَر (breadcrumbs) ربّما، ومسائل SEO، ووسوم العنوان (title tags)، والوسوم الوصفية (meta tags)، والأوصاف وما إلى ذلك. ونحن

[01:22] يمكن أيضًا، بدلًا من تعريف السياق في الجذر وإتاحة الوصول إليه في كلّ مكان، أن نُعرِّف — وسنرى كيف ذلك بالطبع — بعض السياق في مسارٍ مُعيّن. فلنقل هنا مثلاً

[01:34] عندما نفعل ذلك، سَيَكُون هذا السياق متاحًا لهذا المسار فقط ولأيّ من أبنائه (children).

[01:42] ويمكننا فعل ذلك كذلك إذا كانت لَدَينا بعض البيانات التي قَدْ تُستخدَم فقط لمقطعٍ (segment) مُعيّن في شجرة مساراتنا. هذه هي الفكرة العامّة. فلتكن لَدَينا بضعة أمثلة بسيطة ربّما، وربّما إذا شئت يمكننا إجراء

[01:55] فيديو آخر لنمتلك بعض الأمثلة الأكثر واقعية لاستخدام السياق.

[02:01] لكن لِننتقل الآن إلى هنا، وعلينا أن نفتح بضعة ملفّات. فلنفتح ملفّ main.tsx لدينا، ولنفتح أيضًا مسار الجذر لدينا، وهو _root في مجلّد routes لدينا، فلنقل أنّ لَدَينا ربّما نظام

[02:17] مصادقة (authentication). بالطبع ما سنفعله ليس واقعيًا جدًّا، لكن فلنمتلك مجرّد مثالًا بسيطًا حيث لَدَينا مستخدم (user) نحتاج إلى تمريره إلى جميع مساراتنا، وهذا المستخدم إن وُجد فهذا يعني أنّنا في وضع تسجيل الدخول. وإن

[02:29] لم يكن، فهذا يعني أنّنا لسنا في وضع تسجيل الدخول. إذًا في مسار الجذر لديّ سَنُعرِّف ببساطة نوعًا (type) بسيطًا لمستخدمنا. فلنقل أنّنا سَنَمتلك مُعرِّفًا (ID) واسمًا. ثم إذا احتجنا إلى تمرير بعض السياق في مسار الجذر لدينا، فبدلًا من

[02:44] استدعاء createRootRoute نستدعِ createRootRouteWithContext التي يمكننا استيرادها بالطبع من TanStack React Router. والآن يمكننا إزالة هذا. ولكي نحقّق أمان الأنواع (type safety) عندما نستخدم هذا السياق. إذًا

[02:59] عندما نضبط السياق أو نصل إلى السياق نحتاج إلى تحديد نوعه، ويمكننا فعل ذلك بتمرير مُعامَل نمط (generic) هنا، ويمكننا تمرير نوع سياقنا.

[03:09] إذًا في حالتنا فلنُعرِّف واجهة (interface) هنا. فلنسمّيها ربّما RootRouteContext.

[03:16] ولنقل في حالتنا سَنَمتلك مجرّد مستخدم نحتاج إلى تمريره كسياق. وهذا يمكن أن يكون من النوع user أو يمكن أيضًا أن يكون null إذا كنّا خارج وضع تسجيل الدخول (logged out). الآن يمكننا تمرير هذا هنا في هذا المُعامَل النمطي (generic). وكذلك

[03:30] لاحظ أنّ createRootRouteWithContext تُستخدَم بطريقة مختلفة قليلًا. فهذه ليست دالّة نستدعيها مباشرة، بل إنّها دالّة تُعيد دالّة أخرى نحتاج إلى استدعائها. إذًا نحتاج إلى استدعاء

[03:42] هذه الدالّة أولًا هنا، ثم أيّ دالّة أُعيدت من هذه سَنستدعيها لتمرير مكوّننا وما إلى ذلك، فنحتاج إلى إضافة بضعة أقواس هنا فقط. والآن سَنحتاج إلى تمرير سياق

[03:57] ابتدائي (initial context). فإذا ذهبنا هنا، سَنذهب إلى main.tsx، سَنَجد أنّ عندنا الآن خطأ لأنّنا حدّدنا أنّ موجّهنا يمتلك بعض سياق الجذر (root context)، غير أنّنا لا نمرّر أيّ سياق عند إنشاء موجّهنا. إذًا لكي

[04:10] نفعل ذلك علينا أن نمرّر هنا context ونمرّر بعض السياق الابتدائي. في حالتنا لَدَينا المستخدم user وقد يكون null أو مستخدمًا. بالطبع في البداية يمكننا ضبطه ببساطة إلى null ثم يمكننا تعبئته لاحقًا كما

[04:24] سترى الآن. لكن أولًا، قبل أن نرى كيف يمكننا ربّما التلاعب بهذا السياق وتحديثه، وتحديث المستخدم أو إزالته ربّما عندما يسجّل الخروج وما إلى ذلك، فلنرَ أولًا كيف يمكننا استخدامه في مكوّناتنا (components). إذًا كما

[04:38] ذُكر الآن أنّه بعد أن أصبح لَدَينا هذا السياق في جذرنا، يمكننا استخدامه في أيّ مكان، بمن في ذلك مكوّن الجذر (root component) لدينا أو في أيّ مسار ابن (child route) آخر. فلنجرّب استخدامه في مكوّن الجذر لدينا هنا. وهذا يكون باستخدام خطّاف (hook). إذًا في

[04:53] هنا يمكننا الوصول إلى خطّاف داخل مسارنا. إذًا في أيّ مسار — عذرًا — في أيّ مسار، تذكّر أنّ المسار هو هذا الثابت (constant) الذي نُعرِّفه هنا. وفي المسار سَيَكُون لَدَينا وصول إلى useContext أو إلى useRouteContext.

[05:10] وهنا سَيَكُون لَدَينا الوصول إلى مستخدمنا. إذًا ما سأفعله هو أنّه بعد هذا النصّ الموجود في مسار الجذر هنا ربّما، سأضع هذا الترميز (markup) حيث نتحقّق: إذا كان لَدَينا مستخدم فسَنعرض ببساطة نصًّا يقول

[05:24] مرحبًا ثم اسم المستخدم. وإلا فلدينا مجرّد نصّ «مرحبًا أيّها الزائر». إذًا فلنحفظ هذا، وينبغي أن نحصل على «مرحبًا أيّها الزائر». إذا كنا هنا، عند تهيئة موجّهنا، أضفنا ربّما بعض المستخدم — فلنضف بعض

[05:42] مُعرِّف (ID) واسمًا ما هكذا — فينبغي أن نحصل هنا على نصّ الترحيب.

[05:52] إذًا سَيَكُون هذا السياق متاحًا في مكوّناتنا كما رأينا هنا، وأيضًا في دوالّ التحميل (load functions)، وهي دوالّ سنستخدمها من أجل تحميل البيانات في مساراتنا. وهذا موضوع سَنناقشه

[06:05] لاحقًا. لكن أولًا، كما يمكن أن نرى، عندما نمرّر بيانات إلى سياقنا فنحن نمرّر مجرّد بعض البيانات الثابتة (static data) هنا. غير أنّ ما نحتاج إلى فعله هو، بدلًا من القيام بذلك، أن نجعل هذه الحالة عبارة عن حالة React (React state) كي نتمكّن من

[06:19] التلاعب بها من داخل تطبيقنا.

[06:22] ربّما إذا سجّل المستخدم الدخول فنحتاج إلى تعبئته، وإذا سجّل المستخدم الخروج فنحتاج إلى إزالته وما إلى ذلك. إذًا نحن لا نحتاج فقط إلى تمرير بعض البيانات الثابتة، بل نحتاج إلى أن يكون هذا نوعًا ما من حالة React. فلنرَ كيف يمكننا فعل

[06:33] ذلك الآن. إذًا لكي نمرّر بعض الحالة