/
kaws
/
ui-kit-ce
Обзор
Документация
Войти
/
kaws
/
ui-kit-ce
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
packages/hooks/src/useStorage/useStorage.ts
102 строки
4 KB
Урядышев Павел Александрович
chore: устранены предупреждения eslint
25 июл 2025, 14:03
25 июл 2025, 14:03
1bad2f7
Код
Авторство
О чём код?
import * as React from 'react' const DEFAULT_STORAGE_PREFIX = '@v-uik' export type StorageSetValueType<T> = (value: T | ((val: T) => T)) => void type Options = { /** * Префикс для названия свойства в хранилище. */ prefix?: string | ((defaultPrefix: string) => string) } const defaultOptions: Options = { prefix: DEFAULT_STORAGE_PREFIX } /** * Хук для работы со свойствами из LocalStorage или SessionStorage. * При обновлении значения в хранилище через один экзепляр хука, остальные экземпляры, имеющие такие же аргументы `type` и `key`, * также получат обновления. Изменят внутреннее состояние (state) и инициируют перерисовку компонентов, которые используют хук. * * @param type - Тип хранилища, может быть 'local' или 'session'. * @param key - Ключ, по которому будет храниться значение в хранилище. * @param initialValue - Начальное значение, которое будет возвращаться, если в хранилище не найдено значение по ключу. * @param options - Объект с дополнительными настройками. * @param options.prefix * * @returns - Массив, состоящий из значения свойства, хранящегося в хранилище, * и функции, которая позволяет обновить это значение (логика реализована аналогично хуку `useState`). * * @example * const [counter, setCounter] = useStorage('local', 'counter', 0, { prefix: `@v-uik` }) */ export const useStorage = <T>( type: 'local' | 'session', key: string, initialValue: T, { prefix: prefixOption = defaultOptions.prefix }: Options = defaultOptions ): readonly [T, StorageSetValueType<T>] => { const eventKey = `${type}-${key}` const getStorage = React.useCallback( () => (type === 'local' ? window.localStorage : window.sessionStorage), [type] ) key = (() => { const prefix = typeof prefixOption === 'function' ? prefixOption(DEFAULT_STORAGE_PREFIX) : prefixOption return `${prefix ? `${prefix}:` : ''}${key}` })() const getStorageData = () => { try { const item = getStorage().getItem(key) return item ? (JSON.parse(item) as T) : initialValue } catch (error) { console.error(error) return initialValue } } const [storedValue, setStoredValue] = React.useState<T>(getStorageData) const setValue: StorageSetValueType<T> = React.useCallback( (value) => { let valueToStore = initialValue if (value instanceof Function) { const updatedStorageValue = getStorageData() valueToStore = value(updatedStorageValue) } else { valueToStore = value } getStorage().setItem(key, JSON.stringify(valueToStore)) // Создаем событие для обновления состояния в этом и других инстансах хука const event = new Event(eventKey) document.dispatchEvent(event) }, /* eslint-disable-next-line react-hooks/exhaustive-deps */ [initialValue, key, eventKey, getStorage] ) React.useEffect(() => { const updateValueFromStorage = () => { setStoredValue(getStorageData()) } document.addEventListener(eventKey, updateValueFromStorage) return () => { document.removeEventListener(eventKey, updateValueFromStorage) } /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [eventKey]) return [storedValue, setValue] as const }