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

التعامل مع أخطاء معامِلات البحث (Handling Search Params Errors)

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

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

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

الفرع: search-3

[00:01] لكن الآن، ماذا لو عدّل أحدهم — ربما — هذا URL ووضع أنواعًا خاطئة هنا؟ فعندما نتنقّل داخل تطبيقنا، إذا مرّرنا شيئًا خاطئًا فسنحصل على خطأ. وماذا لو كان لَدى أحدهم رابط يحتوي على معلومات

[00:16] خاطئة؟ كيف سنتعامل مع ذلك؟ فلنقل مثلًا أنّنا في sort by هنا نمرّر شيئًا خاطئًا، شيئًا ليس price ولا oldest ولا newest. فسأكتب أيّ شيء هنا. والآن كما ترى

[00:30] سنحصل على خطأ. فيمكننا تخصيص صفحة الخطأ (error page) هذه، وسنتحدّث لاحقًا بمزيد عن معالجة الأخطاء.

[00:38] لكن ما نستطيع فعله أساسًا — عذرًا، ليس هنا؛ في مسار products لدينا — أن نمرّر ببساطة مكوّن خطأ (error component) هنا. وهنا يمكننا ببساطة أن نمرّر دالة نُرجع فيها شيئًا، لنقل في الوقت الحالي وسم p (p tag). لنقل error.

[00:55] إذًا الآن سنحصل على هذا. فيمكنك أن تختار فعل ذلك أي عرض خطأ إذا كانت عندك بيانات خاطئة في معامِلات البحث لديك، أو ربما ستكون تجربةً أفضل أنّك إذا وُجد شيء خاطئ في أحد

[01:10] معامِلات البحث (search parameters) لديك تتراجع (fallback) إلى قيمة افتراضية. فلنرَ كيف يمكننا فعل ذلك أيضًا. ولنجرب ربما ذلك على sort by وحده كمثال، لكن يمكنك فعل ذلك مع كل الخصائص الأخرى كذلك. ففي Zod يمكننا

[01:25] أن يكون لَدَينا catch هنا أي .catch، بحيث إذا كان لَدَينا أي خطأ نوع (type error) هنا في بياناتنا يمكننا توفير قيمة افتراضية.

[01:37] فلنقل newest مثلًا.

[01:40] الآن، لنفتح أيضًا وحدة التحكّم (console) لدينا. إذا حفظنا هذا وحدّثنا الصفحة فلن نحصل على خطأ. وفي معامِلات البحث لدينا سنحصل على newest في sort by. وبالطبع أيضًا، إذا تطلّعت إلى URL،

[01:56] فسيكون قد تغيّر إلى newest.

[01:59] غير أنّه بفعلها بهذه الطريقة سنخسر معلومات النوع (type information) في رابطنا. فعلى سبيل المثال الآن، إذا مرّرنا أيّ شيء هنا فلن نحصل على خطأ نوع، لأنّ نوع هذا سيكون unknown. لذا

[02:14] لإصلاح هذه المشكلة، يوفّر لنا TanStack Router وسيلةً لتوفير قيمة تراجع (fallback) مع الإبقاء على معلومات النوع. فبدلًا من استخدام catch هنا، لنزِل هذا. وما يمكننا فعله أنّنا نستطيع استيراد

[02:28] دالة اسمها fallback من مُهايئ Zod في TanStack (Zod adapter) ثم نغلّف بها enum الخاص بنا، وبالطبع ليس من الضروري أن يكون enum؛ يمكننا أن نغلّف بها أيّ نوع. فلنغلّف هذا بدالة fallback هكذا،

[02:43] ثم بوصفها وسيطًا ثانيًا لـ fallback.

[02:45] في هذا المكان يمكننا تمرير قيمة تراجع (fallback value).

[02:48] لنقل newest. والآن إذا حفظنا هذا وعدنا إلى هنا، فكما ترى فالنوع محفوظ الآن. إذا كان لَدَينا شيء خاطئ هنا فسنحصل على خطأ. وإذا مرّرنا في URL لدينا شيئًا خاطئًا في sort by،

[03:04] فستراجع إلى newest.

[03:08] وبالطبع، كما فعلنا في أحد معامِلاتنا — معامِل sale — ما زال بإمكاننا توفير قيمة افتراضية إن لم نمرّر sort by. فعندما نستخدم fallback يمكننا فعل هذا بعد — بعد إغلاق دالة fallback في

[03:22] هذا المكان، ما زال بوسعنا توفير قيمة افتراضية. فيمكننا أن نجعل الافتراض newest مثلًا. والآن إن لم نمرّر newest — لنزِلها ربما من URL لدينا هكذا.

[03:36] وإذا تطلّعنا في مكان ما من URL لدينا، فسنجد أنّه موجود. فلنذهب إلى هنا. وكما ترى، نحصل على sort by newest رغم أنّنا — رغم أنّنا — لم نمرّره في URL لدينا.

[03:50] وبالطبع فعلتُ هذا لهذا المعامِل وحده، لكن يمكنك فعل المثل مع البقية كذلك، أي توفير قيمة التراجع في حال وُجد شيء خاطئ في URL. إذًا هكذا يمكننا التحقّق من صحة معامِلات البحث وتحديد أنواعها

[04:05] في TanStack Router.

[04:08] شيء واحد يمكنك أن تفعله أيضًا — ولن أفعله أنا، لكن يمكنك إلقاء نظرة عليه إن أحببت — وهو أمر متقدّم قليلًا يتمثّل في تخصيص كيفية تسلسل (serialization) معامِلات البحث.

[04:20] وكما ذكرنا، عندما نمرّر — نمرّر — URL هنا مع معامِلات بحث، سيُسلسَل في هذا URL، ثم سيُحلَّل عندما تستخدمه في دالة load لديك أو في المكوّنات وما إلى ذلك.

[04:34] ويمكنك تخصيص كيفية حدوث هذه العملية: كيف يُسلسَل URL لديك ويُحلَّل وما إلى ذلك. فافتراضيًا يحلّل TanStack Router عنوان URL لديك ويسلسله باستخدام JSON.stringify وJSON.parse.

[04:48] غير أنّه يمكنك تخصيص ذلك بتمرير دالتين parse search و stringify search والقيام هنا بشيء مخصّص. فإذن لدينا بعض الأمثلة هنا، ربما باستخدام base64.

[05:02] يمكنك أن تمرّر دوالّ مخصّصة هنا، وثمّة أمثلة أخرى لديك أيضًا باستخدام مكتبة query string، ويمكنك كذلك استخدامها مع stringify search وparse search.

[05:12] غير أنّه في معظم الحالات، أظنّ أنّ السلوك الافتراضي سيكون كافيًا ربما. لكن اعلم فقط أنّ هذا موجود، في حال كنت في موقف تحتاج فيه إلى تخصيص هذا السلوك. لكن الآن هناك شيء أنت على الأرجح

[05:26] ستحصل عليه في تطبيقك عندما تكون لديك معامِلات بحث كثيرة، وهو أنّك ستملك غالبًا مكوّنًا تستطيع فيه تغيير عوامل التصفية (filters) أو تسمح للمستخدمين بتغيير عوامل التصفية. و

[05:40] في هذه الحالة سنحتاج، بطريقةٍ ما، إلى تحديث معامِلات بحث معيّنة مع الإبقاء على معامِلات البحث الموجودة سلفًا. وقد رأينا فعلًا كيف نفعل ذلك مع معامِلات URL بتمرير دالة إلى خاصية (prop) params هنا.

[05:56] بدلًا من مجرّد كائن — ويمكننا فعل المثل مع معامِلات البحث كذلك. فيمكننا تمرير دالة يتسنّى لك فيها استقبال معامِلات البحث السابقة لديك، ويمكنك إرجاع كائن محدَّث. غير أنّه قبل تجربة

[06:09] ذلك، لنذكر ربما بعض المعلومات الإضافية عن مكوّن Link (الرابط)، لأنّنا لم نناقش بعد كل ما يتعلّق بمكوّن Link.

[06:18] إذًا فلنناقش، ربما، بضعة أمور عنه، ثم نعود إلى خاصية search هذه ونجرب تمرير دالة بدلًا من مجرّد كائن. وحتى الآن، في