| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | import { useEffect, useState, useCallback } from 'react'; |
| |
|
| | export default function useLocalStorage<T>( |
| | key: string, |
| | defaultValue: T, |
| | globalSetState?: (value: T) => void, |
| | storageCondition?: (value: T, rawCurrentValue?: string | null) => boolean, |
| | ): [T, (value: T) => void] { |
| | const [value, setValue] = useState(defaultValue); |
| |
|
| | useEffect(() => { |
| | const item = localStorage.getItem(key); |
| |
|
| | if (!item && !storageCondition) { |
| | localStorage.setItem(key, JSON.stringify(defaultValue)); |
| | } else if (!item && storageCondition && storageCondition(defaultValue)) { |
| | localStorage.setItem(key, JSON.stringify(defaultValue)); |
| | } |
| |
|
| | const initialValue = item && item !== 'undefined' ? JSON.parse(item) : defaultValue; |
| | setValue(initialValue); |
| | if (globalSetState) { |
| | globalSetState(initialValue); |
| | } |
| |
|
| | function handler(e: StorageEvent) { |
| | if (e.key !== key) { |
| | return; |
| | } |
| |
|
| | const lsi = localStorage.getItem(key); |
| | setValue(JSON.parse(lsi ?? '')); |
| | } |
| |
|
| | window.addEventListener('storage', handler); |
| |
|
| | return () => { |
| | window.removeEventListener('storage', handler); |
| | }; |
| | |
| | }, [key, globalSetState]); |
| |
|
| | const setValueWrap = useCallback( |
| | (value: T) => { |
| | try { |
| | setValue(value); |
| | const storeLocal = () => { |
| | localStorage.setItem(key, JSON.stringify(value)); |
| | window?.dispatchEvent(new StorageEvent('storage', { key })); |
| | }; |
| | if (!storageCondition) { |
| | storeLocal(); |
| | } else if (storageCondition(value, localStorage.getItem(key))) { |
| | storeLocal(); |
| | } |
| | globalSetState?.(value); |
| | } catch (e) { |
| | console.error(e); |
| | } |
| | }, |
| | [key, globalSetState, storageCondition], |
| | ); |
| |
|
| | return [value, setValueWrap]; |
| | } |
| |
|