استفاده از URL برای مدیریت state در نسخه ۱۴ Next.js

در چشم انداز همیشه در حال تحول توسعه وب، URL به عنوان یک قهرمان خاموش ظاهر شده است. همانطور که توسعه‌دهندگان فرانت‌اند چالش‌های ادغام یک state manager در سرور کامپوننت را بررسی می‌کنند، URL یک راه حل تازه در توسعه Next.js ارائه می‌دهد.

URL فراتر از نقش سنتی خود به عنوان یک آدرس وب، به یک ابزار مدیریت state قدرتمند تبدیل شده است که نحوه تعامل کاربران و ذخیره تجربیات آنلاین آن‌ها را متحول می‌کند.

فعالیت‌هایی که در زیر داریم کمک می‌کند تا درک کنیم که URL چگونه می‌تواند چنین کارهایی را در پروژه‌های Next.js انجام دهد و به کاربران و توسعه‌دهندگان کمک کند:

  • محتوای مورد نظر خود را با یک لینک ساده به اشتراک می‌گذاریم.
  • صفحات را برای مراجعات بعدی bookmark می‌کنیم.
  • به طور یکپارچه، نتایج جستجو را ذخیره می‌کنیم.

در ادامه قصد داریم تا این مفهوم را با یک مثال عملی در یک سرور کامپوننت بررسی نماییم.

import Link from 'next/link';

export default function ProductPage({
  searchParams,
}: {
  searchParams: { [key: string]: string | string[] | undefined };
}) {
  const selectedColor = (searchParams?.color || 'blue') as string;
  const selectedSize = (searchParams?.size || 'M') as string;

  const sizeVariants = ['S', 'M', 'L', 'XL'];

  return (
    // ...
    <div>
      {sizeVariants.map((size, index) => (
        <Link
          key={index}
          href={`?${new URLSearchParams({
            color: selectedColor,
            size,
          })}`}
          className={`${
            selectedSize === size ? 'bg-blue-500' : 'bg-gray-200'
          } mr-2 inline-block h-8 w-8 text-center leading-8`}
        >
          {size}
        </Link>
      ))}
    </div>
    // ...
  );
}

این کامپوننت یک prop به نام searchParamsرا می‌پذیرد، که یک آبجکت حاوی جفت‌های key-value می‌باشد و پارامترهای query string مربوط به URL را نشان می‌دهد. متغیرهای SelectColorو SelectSizeاز این پارامترها استخراج می‌شوند.

فرض کنید یک صفحه محصول برای یک پیراهن صورتی در سایز “XL” داریم. URL آن ممکن است شبیه به مثال زیر باشد:

https://www.examplestore.com/product-page?color=pink&size=XL

اکنون می‌خواهیم نحوه کمک کد به این موضوع را بررسی کنیم.

مقادیر پیش‌فرض:

در اصل، مقادیر پیش‌فرض به‌عنوان یک شبکه ایمنی عمل می‌کنند و تضمین می‌کنند که کامپوننت به خوبی سناریوهای مختلف را مدیریت می‌کند و در مواجهه با بی‌نظمی‌های احتمالی در داده‌هایی که دریافت می‌کند، پرقدرت باقی می‌ماند.

const selectedColor = (searchParams?.color || 'blue') as string;
const selectedSize = (searchParams?.size || 'M') as string;

تولید لینک:

این خط ویژگی hrefرا برای هر Link ایجاد می‌کند و یک آبجکت URLSearchParamsجدید با رنگ انتخاب شده و اندازه خاص ایجاد می‌نماید.

با ترکیب new URLSearchParams، توسعه‌دهندگان می‌توانند URLهایی ایجاد کنند که استانداردها را رعایت کرده و از سازگاری در مرورگرهای مختلف اطمینان حاصل نمایند.

href={`?${new URLSearchParams({ color: selectedColor, size })}`}

استایل‌دهی:

classNameها به صورت پویا به Linkها استایل می‌دهند. به این صورت که سایز مورد نظر را با پس‌زمینه آبی برجسته می‌کنند و در نتیجه یک نشانه بصری ارائه می‌دهند.

className={`${
  selectedSize === size ? 'bg-blue-500' : 'bg-gray-200'
} mr-2 inline-block h-8 w-8 text-center leading-8`}

در ادامه قصد داریم تا مثالی را در سمت کلاینت که دارای ورودی جستجو است بررسی کنیم.

'use client';

import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import { useSearchParams, usePathname, useRouter } from 'next/navigation';
 
export default function Search() {
  const searchParams = useSearchParams();
  const pathname = usePathname();
  const { replace } = useRouter();
 
  function handleSearch(term: string) {
    const params = new URLSearchParams(searchParams);
    if (term) {
      params.set('query', term);
    } else {
      params.delete('query');
    }
    replace(`${pathname}?${params.toString()}`);
  }
}


return (
    <div className="relative flex flex-1 flex-shrink-0">
      <label htmlFor="search" className="sr-only">
        Search
      </label>
      <input
        className="peer block w-full rounded-md border border-gray-200 py-[9px] pl-10 text-sm outline-2 placeholder:text-gray-500"
        placeholder={placeholder}
        defaultValue={searchParams.get('query')?.toString()}
        onChange={(e) => {
          handleSearch(e.target.value);
        }}
      />
      <MagnifyingGlassIcon className="absolute left-3 top-1/2 h-[18px] w-[18px] -translate-y-1/2 text-gray-500 peer-focus:text-gray-900" />
    </div>
  );
}

قطعه کدی که داریم از هوک‌های navigation سمت کلاینت نسخه Next.js 14 استفاده می‌نماید. useSearchParamsپارامترهای URL فعلی را بازیابی می‌کند، usePathnameنام مسیر فعلی را دریافت می‌کند و userRouterفانکشنالیتی‌های مسیریابی را ارائه می‌دهد. حتی اگر در سمت کلاینت هستیم و می‌توانیم از هوک‌هایی مانند useState استفاده کنیم، اما ما به دلیل مزایایی که استفاده از URL به عنوان state manager ارائه می‌دهد به کار خود ادامه می‌دهیم.

handleSearch:

تابع handleSearchپارامترهای URL را بر اساس عبارت جستجوی ارائه شده، به روز رسانی می‌کند. این تابع از یک آبجکت URLSearchParamsبرای مدیریت پارامترها، تنظیم یا حذف پارامتر query بر اساس اینکه آیا یک عبارت ارائه شده است یا خیر، استفاده می‌کند. این تابع در نهایت، ازreplaceبرای به روز رسانی URL استفاده می‌نماید.

function handleSearch(term: string) {
    const params = new URLSearchParams(searchParams);
    if (term) {
      params.set('query', term);
    } else {
      params.delete('query');
    }
    replace(`${pathname}?${params.toString()}`);
  }

defaultValue:

searchParams.get('query')?.toString() مقدار پارامتر query را از URL بازیابی می‌کند. اگر پارامتر وجود داشته باشد، مقدار آن را برمی‌گرداند. در غیر این صورت، nullرا return می‌کند.

<input
        className="peer block w-full rounded-md border border-gray-200 py-[9px] pl-10 text-sm outline-2 placeholder:text-gray-500"
        placeholder={placeholder}
        defaultValue={searchParams.get('query')?.toString()}
        onChange={(e) => {
          handleSearch(e.target.value);
        }}
      />

اکنون به اشتراک گذاری راحت تجربیات مورد نظر کاربران را بررسی خواهیم کرد.

یکی از قانع‌کننده‌ترین جنبه‌های استفاده از URL به‌عنوان state manager، توانایی یکپارچه آن برای به اشتراک گذاشتن تجربیات مورد نظر کاربران است. کاربری را تصور کنید که در حال بررسی مجموعه‌ای از محصولات صورتی رنگ با سایز XL فروشگاه است. هنگام استفاده از URL به عنوان state manager، تجربیات مورد نظر کاربران پویا شده و به راحتی قابل اشتراک گذاری می‌باشد.

برای مثال، آدرس اینترنتی را در نظر بگیرید: https://www.examplestore.com/product-page?color=pink&size=XL. این لینک یک حالت خاص را در برنامه بیان می‌کند که در این مورد، محصولاتی را به نمایش می‌گذارد که مطابق با ترجیح کاربر، دارای رنگ صورتی و اندازه XL هستند. اتفاق خاص زمانی رخ می‌دهد که کاربر این لینک را به اشتراک بگذارد.

در ادامه فهرستی از نمونه‌هایی وجود دارد که نشان می‌دهد چگونه URL می‌تواند به عنوان یک state manager ایده‌آل، به‌ویژه در زمینه سرور کامپوننت‌ها عمل کند:

  • صفحه بندی: /products?page=2
  • ورودی‌های جستجو: /search?query=shoes&type=sneaker
  • گزینه‌های مرتب‌سازی: /products?category=clothing&sort=price-asc
  • فیلتر کردن بر اساس دسته: /products?category=electronics
  • ترجیحات کاربر: /profile?theme=dark&language=en
  • فرم‌های پویا: /form?step=2

جمع‌بندی

در این مقاله سعی کردیم تا بررسی کنیم که چرا URL می‌تواند به عنوان یک state manager ایده‌آل در سرور کامپوننت‌ها و کلاینت کامپوننت‌های پروژه‌های Next.js مورد استفاده قرار بگیرد. موارد استفاده زیادی در این مورد وجود دارد که ما فقط به چند نمونه از آن‌ها اشاره کردیم.

دیدگاه‌ها:

افزودن دیدگاه جدید