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

مزيدٌ عن مكوّن الرابط (Link)

الدرس 16 من 34 · دورة TanStack Router الكاملة · 9 دقيقة و10 ثانية

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

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

الفرع: more-on-link

[00:01] الروابط (links): كنّا في الخاصية to نمرّر المسار المطلق إلى مسارٍ كلّما احتجنا إلى التنقّل إلى مسارٍ معيّن. فعندما نحتاج مثلًا إلى التنقّل إلى مسار products، نضع هنا المسار الكامل إلى

[00:14] مسار products. ولو كان هذا متداخلًا بطريقةٍ ما، فسنحتاج إلى وضع المسار الكامل هكذا.

[00:21] يمكننا فعل ذلك إمّا هكذا بكتابة اسم المسار يدويًّا، وإن وقع لَدَينا أيّ خطأ إملائي فسنتلقّى خطأ أنواع (type error).

[00:27] أو يمكننا فعل ذلك أيضًا بصورةٍ ديناميكية عبر الاستيراد (import). فأنا الآن في مسار الصفحة الرئيسية (home route)؛ إن احتجنا إلى التنقّل إلى مسار products، فيمكننا الاستيراد من مسار products ذلك الثابت (constant) المسمّى Route الذي نصدّره هنا. وفي هذا

[00:41] الثابت، أي في هذا الكائن، سنجد الخاصية to التي يمكننا بها تمرير مسار مسارنا بصورةٍ ديناميكية. فيمكنني مثلًا استيراد Route من products/index باسم productsRoute، ثم في هنا

[00:56] بدلًا من تمرير هذا هكذا، يمكننا أن نجعله ديناميكيًّا بكتابة productsRoute.to. وسَيُوضَع بذلك، بصورةٍ ديناميكية، مسارُ مسار products. وقد يكون هذا مفيدًا إن غيّرتَ في مرحلةٍ ما اسم مسار

[01:12] وهذا قد يكون غير محتمل، لكن إن فعلتَ فلن تحتاج إلى تحديث روابطك، بما أنّ الخاصية to عندك هنا ديناميكية. ويمكن مع مكوّن الرابط (Link) أيضًا — إضافةً إلى امتلاك مساراتٍ مطلقة — أن نمتلك مساراتٍ نسبية

[01:25] بتمرير الخاصية from إضافةً إلى الخاصية to. ففي الخاصية to يمكن أن يكون المسار نسبيًّا إلى ما نمرّره إلى الخاصية from. فلنشرح ذلك أكثر ربّما بالذهاب إلى أحد المسارات المتداخلة لَدَينا. فلنقل ذا الذي

[01:39] لتحرير منشور: posts/$postId/edit مثلًا. وفلنقل إن كنا هنا نحتاج إلى التنقّل من posts/$postId/edit عائدين إلى مسار posts. إذن بالطبع فلنضف سطرًا جديدًا. وبالطبع يمكننا ببساطة

[01:56] إضافة رابط. فلنقل «كل المنشورات» (all posts). ويمكننا ببساطة إضافة to هنا والتنقّل إلى posts هكذا. وفلنستورد (import) مكوّن Link.

[02:08] والآن فلنجرب زيارة هذا المسار.

[02:10] إذًا posts/$postId/edit بمعرّفٍ ما. وفلنحفظ هذا؛ فسنمتلك عندئذٍ هذا الرابط الذي يمكننا به التنقّل عائدين إلى «كل المنشورات» (all posts). غير أنّه يمكننا أيضًا أن نكرّر هذا الرابط، فلنفعل ذلك ربّما.

[02:24] ويمكننا تمرير الخاصية from هنا. وفي from يمكننا أيضًا أن نكتب يدويًّا المسار الذي نحتاج إلى التنقّل منه؛ فلنقل مسار التحرير هذا: posts/$postId/edit.

[02:38] والآن في الخاصية to يمكننا وضع مسارٍ نسبيٍّ إلى from. فنحتاج إلى التنقّل من هذا المسار إلى posts، فنحتاج إلى الصعود إلى أعلى، ويمكننا الصعود هكذا. وكما ترى نحصل أيضًا على الإكمال التلقائي (auto-completion)، وإن وضعنا مسارًا نسبيًّا خاطئًا

[02:54] هنا فسنتلقّى أيضًا خطأ أنواع. فنحتاج إلى الصعود مستوىً واحدًا ثم الصعود مرةً أخرى ثم الصعود مرةً أخرى ثم الذهاب إلى posts هكذا. وهذا هو المسار إلى posts بالنسبة إلى posts/$postId/edit.

[03:10] وإن أضفنا هنا سطرًا جديدًا وجرّبنا هذا فينبغي أن يعمل أيضًا.

[03:16] وما يمكننا فعله أيضًا هو أنّه بدلًا من ربّما كتابة هذا المسار يدويًّا — بما أنّنا موجودون في هذا المسار أصلًا — فلنكرّر هذا الرابط.

[03:24] فلنضف سطرًا جديدًا. بما أنّنا في هذا المسار فعلًا ولدينا Route هنا، فيمكننا الحصول على المسار الكامل لهذا المسار من كائن Route هذا أيضًا.

[03:33] فبدلًا من كتابة هذا يدويًّا، يمكننا أن نمرّر هنا route.fullPath، وهذا سَيَكُون المسارَ الكامل لمسار التحرير الذي نحدّده هنا.

[03:46] وهذا ينبغي أن يعمل بالطريقة نفسها أيضًا. وفلنقل مثلًا إن كنّا قد أخطأنا هنا: ربّما نصعد مستويين فقط بدلًا من ثلاثة؛ فسنتلقّى خطأ أنواع لأنّ كل شيءٍ، كما نعرف الآن، آمن الأنواع في TanStack

[04:02] Router. الآن فلنقل إن كنا ما نزالنا في مسار التحرير، أي posts/$postId/edit، وربّما نحتاج إلى امتلاك زرّ رجوع (back) يأخذنا إلى المنشور الذي نحرّره. وليس مقصودي بكلمة «رجوع» النقر على زرّ الرجوع في المتصفّح و

[04:17] الانتقال إلى الرابط السابق الذي كنّا نزوره، بل أعني الانتقال من مسار التحرير إلى أبيه (parent) وهو posts/$postId. ويمكننا فعل ذلك أيضًا باستخدام مسارٍ نسبي هو الآخر. وفي هذه الحالة لا نحتاج حتى إلى تمرير

[04:31] from. ما يمكننا فعله هو إضافة رابطٍ فقط. فلنقل «العودة إلى المنشور» (back to post)، وهنا بدلًا من to يمكننا إضافة نقطتين (..) للصعود مستوىً واحدًا في شجرة مساراتنا. وبإمكانك بهذا — إن نقرتَ على «العودة إلى المنشور» (back to post) —

[04:50] أن تصل إلى مسار posts/$postId.

[04:55] غير أنّه إن حدّدتَ from هنا فسنتنقّل إلى أبي ما تمرّره في from، لا إلى أبي المسار الحالي. فإن مرّرنا مثلًا مسار about ثم وضعنا النقطتين هنا فسنتنقّل إلى

[05:11] أب about، وهو ينبغي أن يكون صفحتنا الرئيسية. فلو عدنا الآن إلى هذا المسار لتحرير المنشور ونقرنا على «العودة إلى المنشور» (back to post) فسنعود إلى صفحتنا الرئيسية، صحيح؟ لكن سأزيل هذا. ويمكننا أيضًا بدلًا من النقطتين أن

[05:26] نضيف نقطةً واحدة فقط، ما معناه أنّنا نحتاج إلى التنقّل إلى المسار نفسه الذي نحن فيه حاليًّا. فإن حفظتُ هذا ونقرتُ على «العودة إلى المنشور» (back to post) فلن يحدث شيء. إذن سأعيد تغييرها إلى نقطتين.

[05:41] فمتى يكون التنقّل إلى المسار نفسه مفيدًا؟ يكون مفيدًا عندما نحتاج إلى التنقّل إلى المسار نفسه الذي نحن فيه حاليًّا ونحدّث بعض معاملات البحث (search parameters) التي لدينا في مسارنا. فلنعد ربّما إلى

[05:54] مسار products، وتذكّر أنّنا كنّا نضع هنا بعض معاملات البحث. فلنقل إن كان في مسار products لدينا مكوّنٌ يمكننا من خلاله تحديث مرشّحاتنا (filters) وما إلى ذلك. فنحن نحتاج إلى التنقّل إلى المسار نفسه، أي products،

[06:08] لكن مع تحديث بعض معاملات البحث، ويمكننا استخدام النقطة (.) لفعل ذلك. ففلنضف هنا رابطًا جديدًا باستيراد Link من @tanstack/react-router. وفلنقل إن كنّا نحتاج إلى امتلاك نوعٍ من الترقيم الصفحي (pagination) حيث

[06:25] نحتاج إلى الذهاب إلى الصفحة التالية، فنحتاج إلى الاحتفاظ بكل ما عندنا في مرشّحاتنا لكن تحديث كائن الترقيم الصفحي pagination هذا بصفحتنا التالية. فتذكّر أنّ pagination عندنا كائنٌ فيه page و pageSize. فلنقل إن كنّا نحتاج

[06:40] إلى الاحتفاظ بكل شيء لكن تحديث page داخل كائن pagination هذا.

[06:46] فلنقل «الذهاب إلى الصفحة التالية» (go to next page)، وهنا نحتاج إلى التنقّل إلى المسار نفسه الذي نحن فيه، أي products، فيمكننا وضع نقطةٍ فقط. غير أنّه في search يمكننا الآن امتلاك دالّة من خلالها سنحصل على معاملات البحث السابقة

[07:00] لَدَينا ويمكننا أن نُعيد فقط كائنًا بمعاملات البحث الجديدة.

[07:06] فنحتاج إلى الاحتفاظ بمعاملات البحث السابقة لكن تحديث pagination فقط — عذرًا — pagination، و pagination كائنٌ، فنحتاج أيضًا إلى الاحتفاظ بكل ما كان فيه. إذن previous

[07:20] . pagination ونحدّث page فقط. أمّا page فنحتاج إلى زيادتها، فيمكننا ببساطة أن نحصل على الصفحة السابقة: previous.pagination.page ونضيف واحدًا. فإن لم يكن pagination موجودًا لأيّ

[07:38] سبب، فنحتاج ربّما إلى الرجوع إلى الصفحة 1. فيمكننا أن نضع هذا بين قوسين (parentheses) ونكتب «أو 1» هنا. والآن إن حفظنا هذا فسنمتلك هذا الرابط للذهاب إلى الصفحة التالية.

[07:52] وفلنفتح أيضًا ربّما وحدة التحكّم (console) لنرى معاملات البحث لدينا.

[07:57] فحاليًّا لَدَينا pagination بالصفحة 1. إن نقرنا على «الذهاب إلى الصفحة التالية» (go to next page) فينبغي أن يكون لَدَينا pagination بالصفحة 2. ونقرٌ آخر: الصفحة 3 وهكذا. وبالطبع ينبغي أن ينعكس هذا في عنوان URL أيضًا. وإن كنّا

[08:12] نحمّل البيانات بالاعتماد على معامل البحث page هذا هنا، فينبغي أن تُعاد بياناتنا تحميلها وأن نجلِب (fetch) صفحتنا الجديدة أيضًا. رائع. وآخر أمرٍ أودّ ذكره عن هذا المكوّن Link أنّه يمكنك تمرير الهاش (hash) أيضًا.

[08:26] فلنذهب إلى home ربّما هنا وفي هنا أيضًا. وفلنضف في كل رابطٍ لَدَينا هذه الخاصية hash ونمرّر بها شيئًا ما ربّما.

[08:38] فلنقل إن احتجتَ إلى التنقّل إلى قسمٍ في صفحتك، وهو div يمتلك معرّفًا (ID)، معرّفًا محدَّدًا، فيمكننا عندها تمرير هذا المعرّف هنا. فلنقل مثلًا section-1.

[08:51] وبفعل ذلك سَيُضاف الهاش (hash) إلى عنوان URL. فإذا نقرنا على هذا الرابط الآن، وكما ترى، فسنمتلك هذا الـ hash هنا. وإن كان في مسارنا div بهذا المعرّف فسننتقل بالتمرير (scroll) إلى هذا الجزء في

[09:06] صفحتنا. بالطبع لَدَينا لا نملكه حاليًّا، لكن الفكرة مفهومة.