در این سؤال، از کتابخانهی 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
راهاندازی پروژه
برای اجرای پروژه، باید 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 }],
}
فیلد 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
}
آرایهای که فرم از روی آن ساخته میشود (متغیر 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
اما به دلایلی نیاز داریم از فرمت متفاوتی برای ساخت این آدرس استفاده کنیم؛ به اینصورت که برای پشت سر هم قرار دادن پارامترها به جای کارکتر&
از کارکتر+
و برای جدا کردن key و value بهجای کارکتر=
از ~
استفاده میکنیم. همچنین در مواردی که یک آرایه از مقادیر داریم (این اتفاق فقط در المان checkbox group
رخ میدهد)، برای جدا کردن آنها از هم به جای ,
از کارکتر --
استفاده میکنیم (ترتیب مقادیر مهم نیست). برای مثال، این پارامترهای رایج آدرس:
?name1=value1&name2=v1,v2,v3
به این صورت تبدیل میشوند:
?name1~value1+name2~v1--v2--v3
و در صورت تجزیه (parse) این پارامترها به آبجکت زیر میرسیم:
{
"name1": "value1",
"name2": ["v1", "v2", "v3"]
}
نکات
- فیلدی که مقداری ندارد نباید در پارامترهای جستجو (query params) آدرس ظاهر شود.
- در صورتی که روی دکمههای پاک کردن (clear) پایین صفحه کلیک شود، باید پارامتر موردنظر از آدرس مربوطه پاک شود و همزمان مقدار
input
متصل به آن فیلد پاک شود. - در صورتی که یک فیلد دارای
children
پاک شود، در اینصورت باید تمامی فرزندانش نیز از آدرس پاک شوند. - فیلدهای فیلتر بایستی مقداردهی اولیه شوند، بهطوری که در زمان بارگذاری صفحه، در صورتی که آدرس دارای پارامترهای جستجو (query params) باشد، باید بلافاصله این مقادیر با فرم هماهنگ شوند و فیلدهای فرم با مقادیر آدرس پر شوند.
- شما تنها مجاز به اعمال تغییرات در فایل
hooks/useFilter.js
هستید. - تنها مجاز به استفاده از کتابخانههای ذکر شده در صورت سوال هستید.
آنچه باید آپلود کنید
پس از پیادهسازی موارد خواستهشده، فایل useFilter.js
را آپلود کنید.
ارسال پاسخ برای این سؤال