niels segers

use-local-forage

A hook for storing data in localForage. It uses an event system to ensure all listeners are notified when the data is updated. This removes the need for manual state management through a context.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import localForage from 'localforage'; import { useCallback, useEffect, useState } from 'react'; localForage.config({ name: 'foo', }); export default function useLocalForage<T>( key: string, initialValue: T, ): [T, (value: T) => void, boolean] { const event = `event:${key}`; const [isInitialized, setIsInitialized] = useState(false); const [storedValue, setStoredValue] = useState(initialValue); const retrieve = useCallback(async () => { try { const value: T | null = await localForage.getItem(key); setStoredValue(value == null ? initialValue : value); } catch (err) { console.error(err); } }, [initialValue, setStoredValue, key]); const store = useCallback( async (value: T) => { try { setStoredValue(value); await localForage.setItem(key, value); } catch (err) { console.error(err); } finally { window.dispatchEvent(new Event(event)); } }, [key, event, setStoredValue], ); useEffect(() => { if (isInitialized) { return; } retrieve(); setIsInitialized(true); }, [isInitialized, retrieve]); useEffect(() => { window.addEventListener(event, retrieve); return () => { window.removeEventListener(event, retrieve); }; }, [event, retrieve]); return [storedValue, store, isInitialized]; }