useViewParams
نمای یک صفحه (بازه، تب، فیلترها، مرتبسازی، چیدمان) در نشانی صفحه — تنها راه DS؛ پیوند و «برگشت» همان نما را باز میکنند
معرفی
هوک useViewParams نمای یک صفحهٔ فهرست، داشبورد یا جزئیات را در نشانی صفحه نگه میدارد: پیوندی که کسی برایتان میفرستد همان بازه، همان تب و همان فیلترها را باز میکند، «برگشت» مرورگر نمای قبلی را برمیگرداند، و دکمهٔ «کپی پیوند این نما» یک خط است.
تا 7.8 DS نوشتن نشانی را از صفحه ممنوع کرده بود («فیلتر هرگز در URL نه»). دلیلش درست بود: سه اجرای X5 سه جور پارامتر نوشتند (نام، آرایه، تاریخ، push یا replace، خواندن در اولین رندر). ولی «نه» پاسخ نیاز واقعی نیست — چهار سند طراحی مستقل پیوند عمیق و نمای قابلاشتراک را خواستند — و دلیل ممنوعیت («چند راه») با ساختن یک راهِ DS از بین میرود. پس قاعده برنگشت، کامل شد: بهجای «هرگز URL»، «URL فقط با useViewParams». هر چیزی که پیشتر ممنوع بود (useSearchParams، useFilterParams/FilterProvider، history.replaceState در فایلی که ListPage یا DashboardPage دارد) همچنان گزارش میشود؛ useViewParams و useUrlQuery مجازند.
چه زمانی استفاده کنیم
- بازه، تب، فیلترها، مرتبسازی یا چیدمانِ (کارت/جدول) یک صفحه که باید با پیوند به اشتراک گذاشته شود یا پس از «برگشت» بماند
- دکمهٔ «کپی پیوند» روی یک صفحهٔ تحلیلی
چه زمانی استفاده نکنیم
- متنی که کاربر هنوز در حال تایپ آن است: state جزء. جستوجوی ارسالشده
useUrlQueryاست - انتخاب ردیفها، حالت باز یک منو، جای یک فید با مکاننما: state جزء
- جزئیات باز یک ردیف در شیت:
useQueryParamSheet؛ کشوی موجودیت:useEntityDrawer - دادهای که اندازهٔ یک درخواست دارد (شمارهٔ صفحهٔ cursor، شناسهٔ نتیجه): state جزء
استفاده
import { arrayParam, enumParam, periodParam, useViewParams } from '@partodata/ui/templates'
// یک بار، در سطح ماژول: طرح صفحه است، state نیست
const VIEW = {
range: periodParam('30d'), // 7d · 30d · 90d · all · 2026-09-01_2026-09-30 (ASCII؛ جلالی فقط در نمایش)
tab: enumParam(['overview', 'posts'] as const, 'overview'),
level: arrayParam<'urgent' | 'high' | 'medium' | 'low'>([]),
view: enumParam(['cards', 'table'] as const, 'cards'),
}
function Issues() {
const [view, setView, { href, reset }] = useViewParams(VIEW)
return (
<ListPage
title="مسائل رصدشده"
filtered={view.level.length > 0}
onClearFilters={() => reset(['level'])}
secondaryActions={<CopyButton value={href({}, { absolute: true })} label="کپی پیوند این نما" />}
/* … */
/>
)
}setView({ level: ['urgent'] }) // یک ورودی تاریخچه جایگزین میشود: ?level=urgent
setView({ tab: 'posts' }, { history: 'push' }) // تب: «برگشت» به تب قبلی برمیگردد
setView((current) => ({ page: current.tab === 'posts' ? 1 : current.page })) // از نشانیِ همین لحظه- اولین رندر از نشانی خوانده میشود (سرور و رندر hydration مقدار پیشفرض میگویند، و بلافاصله نشانی میرسد).
- مقداری که با پیشفرض برابر باشد از نشانی حذف میشود: نشانی ساده همان نمای پیشفرض است.
- ارقام فارسی و عربیهندی نشانی به ASCII خوانده میشوند؛ مقدار ناخوانا همان پیشفرض است.
- فقط پارامترهای طرح نوشته میشوند؛ دیگران (
q، شناسهٔ کشو) دستنخورده میمانند. - بدون
history: 'push'ورودی تاریخچه جایگزین میشود، تا «برگشت» برای رفتن بین صفحهها مفید بماند نه برای هر دستکاری فیلتر.
سازندههای پارامتر
| سازنده | مقدار | نوشته میشود |
|---|---|---|
enumParam(values, default) | یکی از مقدارهای بسته (تب، مرتبسازی، چیدمان) | tab=posts |
periodParam(default) | 7d، 30d، all یا بازهٔ دقیق میلادی | range=2026-09-01_2026-09-30 |
arrayParam(default, { allowed }) | فهرست مقدارها؛ مقدار ناشناخته افتاده میشود | level=urgent,high |
stringParam(default, { maxLength }) | متن کوتاه | name=… |
numberParam(default, { min, max, integer }) | عدد | page=3 |
booleanParam(default) | سوئیچ | mine=1 |
پارامترها
| پارامتر | نوع | توضیح |
|---|---|---|
schema | ViewSchema | نام پارامتر نشانی ← سازنده |
options | UseViewParamsOptions | تنظیمات اختیاری |
UseViewParamsOptions
مقدار بازگشتی
[view, setView, { href, reset }]
نکتهٔ روتر
هوک فقط با History API کار میکند، پس با Next.js App Router (که pushState و replaceState را میپذیرد)، react-router و صفحهٔ ساده کار میکند و روتر چیزی نمیخواهد. useLocation() روتر در تغییرِ نشانی بهروز میشود؛ خود هوک با رویداد خودش و popstate هماهنگ است.
هوکهای مرتبط
- جستوجوی ارسالشده در URL →
useUrlQueryاز@partodata/ui/templates - جزئیات باز یک ردیف →
useQueryParamSheet - وضعیت یک
FilterProviderدرCustomPage→useFilterParams