پرتوپرتو

useIsMobile

تشخیص viewport موبایل با MediaQuery — مقاومت در برابر SSR

معرفی

هوک useIsMobile تشخیص می‌دهد که آیا عرض viewport از breakpoint موبایل (768px) کمتر است یا خیر. از matchMedia استفاده می‌کند و به تغییرات اندازه صفحه واکنش نشان می‌دهد.

چه زمانی استفاده کنیم

  • تغییر layout بین موبایل و دسکتاپ (مثلاً نمایش Sheet به جای Dialog)
  • نمایش/مخفی کردن عناصر UI بر اساس اندازه صفحه
  • تغییر رفتار کامپوننت‌ها (مثلاً حذف tooltip در موبایل)

چه زمانی استفاده نکنیم

  • برای استایل‌دهی ساده — از Tailwind responsive classes (sm:, md:) استفاده کنید
  • برای مخفی کردن عناصر — hidden sm:block کافی است
  • وقتی SSR critical است و باید اولین render صحیح باشد

استفاده

import { useIsMobile } from '@parto-system-design/ui'

function MyComponent() {
  const isMobile = useIsMobile()

  return isMobile ? (
    <Sheet>
      <SheetContent>محتوای موبایل</SheetContent>
    </Sheet>
  ) : (
    <Dialog>
      <DialogContent>محتوای دسکتاپ</DialogContent>
    </Dialog>
  )
}

نکته مهم: رفتار SSR

مراقب SSR باشید

مقدار اولیه در سرور undefined است که به false تبدیل می‌شود. اگر layout اولیه بر اساس این هوک تغییر می‌کند، ممکن است hydration mismatch رخ دهد. برای جلوگیری از این مشکل، از Tailwind responsive classes استفاده کنید یا render شرطی را تا بعد از mount تأخیر بیندازید.

// الگوی امن برای جلوگیری از hydration mismatch
function SafeComponent() {
  const isMobile = useIsMobile()
  const [mounted, setMounted] = React.useState(false)

  React.useEffect(() => setMounted(true), [])

  if (!mounted) return <Skeleton className="h-10 w-full" />

  return isMobile ? <MobileView /> : <DesktopView />
}

پارامترها

این هوک هیچ پارامتری دریافت نمی‌کند.

مقدار بازگشتی

نوعتوضیح
booleantrue اگر عرض viewport کمتر از 768px باشد

جزئیات فنی

  • Breakpoint: 768px (ثابت، قابل تنظیم نیست)
  • مقدار اولیه SSR: false (چون !!undefined === false)
  • واکنش‌پذیر: بله — با تغییر اندازه پنجره به‌روزرسانی می‌شود
  • Listener: از matchMedia استفاده می‌کند (بهینه‌تر از resize event)

هوک‌های مرتبط

  • اگر نیاز به تشخیص جهت متن (RTL/LTR) دارید → useDocumentDirection
  • اگر نیاز به قفل اسکرول دارید (مثلاً هنگام باز بودن modal) → useScrollLock