useLocalStorage
همگامسازی state با localStorage — با سریالیزاسیون JSON و مقاوم در برابر SSR
معرفی
هوک useLocalStorage مشابه useState عمل میکند، اما مقدار را در localStorage ذخیره میکند تا بین refresh صفحه و session ها باقی بماند.
چه زمانی استفاده کنیم
- ذخیره ترجیحات کاربر (مثلاً حالت نمایش grid/list)
- نگهداری وضعیت فیلترهای جدول بین بازدیدها
- ذخیره draft فرمها
چه زمانی استفاده نکنیم
- برای دادههای حساس (رمز عبور، توکن) — از httpOnly cookie استفاده کنید
- برای دادههای حجیم — localStorage محدودیت ~5MB دارد
- برای state مشترک بین tab ها — از
BroadcastChannelیاstorageevent استفاده کنید
استفاده
import { useLocalStorage } from '@partodata/ui'
import { EntityLayoutToggle } from '@partodata/ui/social'
function SettingsPanel() {
const [viewMode, setViewMode] = useLocalStorage<'card' | 'row'>('view-mode', 'card')
return <EntityLayoutToggle layouts={['card', 'row']} value={viewMode} onValueChange={setViewMode} />
}الگوی رایج: ذخیرهٔ نمای فهرست
ترجیح کاربر (مثل نمای شبکه یا فهرست) بعد از بارگذاری دوباره میماند؛ جستوجو، فیلترها و شمارهٔ صفحهٔ یک
ListPage وضعیت خود کامپوننتاند (React.useState) و ذخیره نمیشوند:
function InfluencersPage() {
const [view, setView] = useLocalStorage<'tile' | 'row'>('influencers-view', 'row')
const rows = data?.items ?? []
return (
<ListPage
title="اینفلوئنسرها"
toolbarEnd={<EntityLayoutToggle layouts={['tile', 'row']} value={view} onValueChange={setView} />}
skeleton={view === 'tile' ? 'cards' : 'table'}
state={pageState({
data: data?.items,
isLoading,
error,
onRetry: load,
emptyCopy: { title: 'هنوز اینفلوئنسری ثبت نشده است' },
})}
>
{view === 'tile' ? (
<div className="grid grid-cols-[repeat(auto-fill,minmax(min(var(--layout-tile-min-width),100%),1fr))] gap-layout-block-gap">
{rows.map((row) => (
<Account key={row.id} account={row} layout="card" />
))}
</div>
) : (
<DataTable columns={columns} data={rows} />
)}
</ListPage>
)
}پارامترها
| پارامتر | نوع | توضیح |
|---|---|---|
key | string | کلید localStorage |
initialValue | T | مقدار پیشفرض اگر کلید وجود نداشته باشد |
مقدار بازگشتی
| نوع | توضیح |
|---|---|
[T, (value: T | ((prev: T) => T)) => void] | مشابه useState — مقدار فعلی و تابع setter |
جزئیات فنی
- SSR-safe: در سرور مقدار
initialValueبرمیگرداند - سریالیزاسیون: از
JSON.stringify/parseاستفاده میکند - خطاپذیر: اگر localStorage پر باشد یا مرورگر در حالت خصوصی باشد، بدون خطا ادامه میدهد
- Setter تابعی: مانند
useState، میتوانید تابع updater ارسال کنید
هوکهای مرتبط
- برای debounce کردن مقدار قبل از ذخیره → useDebounce