Query Parameters: پارامترهای اختیاری در انتهای URL

در درس قبل با Route Parameters آشنا شدیم: بخشی از خود مسیر که به یک شناسه ضروری اشاره دارد، مثل شناسه محصول. اما داده‌هایی مثل عبارت جست‌وجو، فیلتر دسته‌بندی یا شماره صفحه، معمولاً بخشی از ساختار اصلی مسیر نیستند؛ این‌ها Query Parameters نام دارند و این درس به آن‌ها می‌پردازد.

ساختار Query Parameters در URL

Query Parameters پس از علامت ? در انتهای URL می‌آیند و با & از هم جدا می‌شوند:

/products?category=fruit&page=2

در این آدرس، category و page دو Query Parameter جداگانه‌اند، با مقادیر fruit و 2.

چرا این‌ها جدا از Route Parameters هستند

تفاوت اصلی در این است که Route Parameterها بخشی از ساختار Route هستند (باید تعریف شوند تا مسیر اصلاً تطبیق پیدا کند)، اما Query Parameterها کاملاً اختیاری‌اند و هیچ تأثیری روی این‌که کدام Route تطبیق پیدا می‌کند ندارند. مسیر /products با یا بدون ?category=fruit، هر دو همان یک Route را فعال می‌کنند؛ فقط محتوای داخل کامپوننت، بر اساس وجود یا نبود این مقدار، می‌تواند رفتار متفاوتی داشته باشد.

خواندن Query Parameters با useSearchParams

import { useSearchParams } from "react-router-dom";

function ProductsPage() {
  const [searchParams] = useSearchParams();
  const category = searchParams.get("category");

  return <p>دسته فعلی: {category ?? "همه دسته‌ها"}</p>;
}

useSearchParams یک آبجکت شبیه URLSearchParams استاندارد مرورگر برمی‌گرداند؛ متد get روی آن، مقدار یک پارامتر را می‌خواند یا اگر وجود نداشته باشد، null برمی‌گرداند.

تغییر Query Parameters

همان Hook، یک تابع برای به‌روزرسانی هم در اختیار می‌گذارد:

function ProductsPage() {
  const [searchParams, setSearchParams] = useSearchParams();

  function handleCategoryClick(category) {
    setSearchParams({ category });
  }

  return <button onClick={() => handleCategoryClick("fruit")}>میوه</button>;
}

فراخوانی setSearchParams، URL نوار آدرس را به‌روزرسانی می‌کند (مثلاً به /products?category=fruit)، بدون بارگذاری مجدد صفحه؛ دقیقاً همان رفتاری که در درس اول این فصل درباره Client-Side Routing دیدیم.

چرا گاهی بهتر از useState محلی است

یک فیلتر که در Query Parameters نگه داشته می‌شود، چند مزیت نسبت به یک useState ساده دارد: کاربر می‌تواند URL را ذخیره یا به اشتراک بگذارد و همان فیلتر دوباره اعمال شود؛ دکمه بازگشت مرورگر، فیلتر قبلی را بازمی‌گرداند؛ و با رفرش کامل صفحه، فیلتر از بین نمی‌رود. این‌ها دقیقاً مزایایی هستند که یک State کاملاً محلی داخل کامپوننت نمی‌تواند بدهد.

ترکیب با دریافت داده

مثل Route Parameters، مقدار Query Parameters هم معمولاً به‌عنوان Dependency در دریافت داده استفاده می‌شود:

const category = searchParams.get("category");
const { data } = useFetch(`/api/products?category=${category ?? ""}`);

مثال قابل اجرا

در این مثال شبیه‌سازی‌شده، بدون کتابخانه واقعی Routing، همان ایده پایه خواندن و تغییر یک Query Parameter دیده می‌شود.

شبیه‌سازی ساده Query Parameters
برای دیدن پیش‌نمایش کامپوننت، روی Run بزنید.

جمع‌بندی

Query Parameters، بخش اختیاری و کلید-مقداری URL پس از علامت ? هستند که برای داده‌هایی مثل فیلتر، جست‌وجو یا صفحه‌بندی مناسب‌اند و بر خلاف Route Parameters، در تطبیق خود Route نقشی ندارند. با useSearchParams می‌توان آن‌ها را خواند و تغییر داد؛ نگه‌داشتن این نوع داده در URL، امکان اشتراک‌گذاری و بازگشت با دکمه Back مرورگر را فراهم می‌کند. در درس بعدی، به Navigation و Links می‌پردازیم.