لینک‌های مفید برای شرکت در مسابقه:

در طول مسابقه می‌توانید سؤالات خود را از قسمت «سؤال بپرسید» مطرح کنید.

هوک فیلتر


در این سؤال، از کتاب‌خانه‌ی react-router-dom@6 استفاده شده است.


ظاهر برنامه

در دیجی‌کال‍ا تعداد زیادی داده وجود دارد که برخی اوقات لازم است آن‌ها را فیلتر کنیم. حال، می‌خوایم راهی پیدا کنیم که این فیلتر اعمال‌شده را به راحتی با بقیه به اشتراک بگذاریم. برای این کار، تصمیم گرفته‌ایم یک هوک بنویسیم که کارش هماهنگ کردن و اتصال state فرم فیلتر با آدرس صفحه است. بنابراین شما باید در کامل کردن این هوک (که آن را useFilter نامیده‌ایم) به ما کمک کنید.

جزئیات پروژه🔗

پروژه‌ی اولیه را از این لینک دانلود کنید.

ساختار فایل‌های پروژه
useFilter
├── public
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── assets
│   │   ├── css
│   │   │   └── index.css
│   │   └── font
│   │       └── Vazir.ttf
│   ├── components
│   │   ├── chips
│   │   │   ├── chips.css
│   │   │   └── index.jsx
│   │   ├── formInput
│   │   │   ├── Checkbox
│   │   │   │   ├── Checkbox.css
│   │   │   │   └── index.jsx
│   │   │   ├── CheckboxGroup
│   │   │   │   ├── CheckboxGroup.css
│   │   │   │   └── index.jsx
│   │   │   ├── Dropdown
│   │   │   │   └── index.jsx
│   │   │   ├── RangeInput
│   │   │   │   ├── RangeInput.css
│   │   │   │   └── index.jsx
│   │   │   ├── TextInput
│   │   │   │   └── index.jsx
│   │   │   ├── Textarea
│   │   │   │   └── index.jsx
│   │   │   ├── FilterForm.jsx
│   │   │   ├── FormClear.jsx
│   │   │   └── FormItem.jsx
│   │   └── Location.jsx
│   ├── constants
│   │   └── FormType.js
│   ├── data
│   │   └── formData.js
│   ├── hooks
│   │   └── useFilter.js
│   ├── App.jsx
│   └── index.jsx
└── package.json
Plain text
راه‌اندازی پروژه

برای اجرای پروژه، باید Node.js و npm را از قبل نصب کرده باشید.

  • پروژه‌ی اولیه را دانلود و از حالت فشرده خارج کنید.
  • در پوشه‌ی useFilter، دستور npm install را برای نصب نیازمندی‌ها اجرا کنید.
  • در همین پوشه، دستور npm start را برای راه‌اندازی پروژه اجرا کنید.

داده‌ی لازم برای ساخت فرم به‌صورت یک آرایه به هوک useFilter پاس داده می‌شود. هر عضو این آرایه معادل یک المان (input element) از فرم است. آبجکت زیر شامل تمامی prop ها است که به المان‌ها داده می‌شود. بعضی از این prop ها مربوط به نوع خاصی از المان‌ها هستند. برای مثال، options فقط مربوط به dropdown و checkbox group است.

{
  "type": "text"|"number"|"dropdown"|"textarea"|"checkbox"|"checkbox-group",
  "name": string,
  "label": string,
  "children"?: string[],
  "parent"?: string,
  "options": [{ value: string|number, title: string|number }],
}
JSON

فیلد options🔗

همان‌طور که گفته شد، این فیلد مختص dropdown و checkbox group است.

فیلد parent و children🔗

بعضی از المان‌های فرم ممکن است دارای وابستگی به المان دیگری باشند. این وابستگی در فرزند با فیلدی به نام parent که یک رشته شامل نام پدر است، نمایش داده می‌شود و در المان پدر با فیلدی به نام children که شامل آرایه‌ای از رشته‌ها شامل نام (فیلد name) فرزندان است.

اتصال (binding) دوطرفه🔗

هوک خواسته‌شده باید یک اتصال (binding) دوطرفه بین پارامترهای جستجوی آدرس (query params) و فیلدهای فرم داشته باشد، به این معنی که با هر تغییر در المان‌های فرم، بلافاصله آدرس به روزرسانی شود و برعکس. این هوک باید یک آبجکت شامل کلیدهای زیر برگرداند:

{
  "filterState": {
    "name": value
  }
  "setFilterState": (filterState)=>void
  "onChange": (e, name, type)=>void
  "onClear": (name)=>void
  "onClearAll": ()=>void
}
JSON

آرایه‌ای که فرم از روی آن ساخته می‌شود (متغیر formData) به‌عنوان ورودی به هوک داده می‌شود.

متغیر filterState و تابع setFilterState🔗

این دو مورد، عملکردی معادل متغیر و تابع از هوک معروف useState را دارند. متغیر یک آبجکت است که هر کلید آن باید برابر با نام (فیلد name) از المان فرم باشد و مقدار آن هم مقدار آن المان است (فیلد value).

تابع onChange🔗

این تابع هنگام تغییر هر المان فرم صدا زده می‌شود.

تابع onClear🔗

در پایین صفحه، دکمه‌هایی برای پاک کردن مقادیر المان‌های فرم‌ وجود دارد. با کلیک کردن بر روی این دکمه‌ها، باید مقدار المان مورد نظر از فرم پاک شود و هم‌زمان این مقدار از آدرس هم پاک شود. این تابع به عنوان ورودی نام (فیلد name) المان موردنظر را دریافت می‌کند.

نکته: در صورتی که مقدار المان پدر پاک شود و یا تغییر کند، مقدار المان فرزند حتماً باید ریست شود، یعنی هم از آدرس پاک شود و هم مقدار input مربوطه از فرم خالی شود.

تابع onClearAll🔗

در صورتی که روی دکمه‌ی پاک کردن همه کلیک شود، مسلماً باید تمامی مقادیر المان‌ها پاک شود و آدرس به حالت / برود.

تجزیه و ترکیب آدرس (url parser & url stringify)🔗

همان‌طور که می‌دانید، در حالت کلی پارامترهای جستجوی آدرس (query parameter) به‌صورت زیر ساخته می‌شوند:

  ?name1=value1&name2=value2&name3=v1,v2,v3
Plain text

اما به دلایلی نیاز داریم از فرمت متفاوتی برای ساخت این آدرس استفاده کنیم؛ به این‌صورت که برای پشت سر هم قرار دادن پارامترها به جای کارکتر& از کارکتر+و برای جدا کردن key و value به‌جای کارکتر= از ~ استفاده می‌کنیم. هم‌چنین در مواردی که یک آرایه از مقادیر داریم (این اتفاق فقط در المان checkbox group رخ می‌دهد)، برای جدا کردن آن‌ها از هم به جای , از کارکتر -- استفاده می‌کنیم (ترتیب مقادیر مهم نیست). برای مثال، این پارامترهای رایج آدرس:

?name1=value1&name2=v1,v2,v3
Plain text

به این صورت تبدیل می‌شوند:

 ?name1~value1+name2~v1--v2--v3
Plain text

و در صورت تجزیه (parse) این پارامترها به آبجکت زیر می‌رسیم:

{
    "name1": "value1",
    "name2": ["v1", "v2", "v3"]
}
JSON

نکات🔗

  • فیلدی که مقداری ندارد نباید در پارامترهای جستجو (query params) آدرس ظاهر شود.
  • در صورتی که روی دکمه‌های پاک کردن (clear) پایین صفحه کلیک شود، باید پارامتر موردنظر از آدرس مربوطه پاک شود و همزمان مقدار input متصل به آن فیلد پاک شود.
  • در صورتی که یک فیلد دارای children پاک شود، در این‌صورت باید تمامی فرزندانش نیز از آدرس پاک شوند.
  • فیلدهای فیلتر بایستی مقداردهی اولیه شوند، به‌طوری که در زمان بارگذاری صفحه، در صورتی که آدرس دارای پارامترهای جستجو (query params) باشد، باید بلافاصله این مقادیر با فرم هماهنگ شوند و فیلدهای فرم با مقادیر آدرس پر شوند.
  • شما تنها مجاز به اعمال تغییرات در فایل hooks/useFilter.js هستید.
  • تنها مجاز به استفاده از کتاب‌خانه‌های ذکر شده در صورت سوال هستید.

آن‌چه باید آپلود کنید🔗

پس از پیاده‌سازی موارد خواسته‌شده، فایل useFilter.js را آپلود کنید.

ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.