Sha256: 6e54381221865180e018aede229779897e23875a7b20a8aa5fbbd663beb78a6f
Contents?: true
Size: 1.59 KB
Versions: 27
Compression:
Stored size: 1.59 KB
Contents
import { useState, useEffect, useCallback, useRef } from 'react'; import debounce from 'lodash/debounce'; import isEqual from 'lodash/isEqual'; interface AutosaveStatus { saving: boolean; saved: boolean; error: string | null; } export function useAutosave<T>( data: T, onSave: (data: T) => Promise<void>, debounceMs: number = 1000 ) { const [status, setStatus] = useState<AutosaveStatus>({ saving: false, saved: false, error: null }); const previousSerializedData = useRef(JSON.stringify(data)); const debouncedSave = useCallback( debounce(async (newData: T) => { setStatus(prev => ({ ...prev, saving: true, error: null })); try { await onSave(newData); previousSerializedData.current = JSON.stringify(newData); // Update reference after saving setStatus({ saving: false, saved: true, error: null }); // Reset "saved" status after 3 seconds setTimeout(() => { setStatus(prev => ({ ...prev, saved: false })); }, 4000); } catch (err) { setStatus({ saving: false, saved: false, error: err instanceof Error ? err.message : 'Failed to save changes' }); } }, debounceMs), [onSave, debounceMs] ); useEffect(() => { // Serialize current data for deep comparison const serializedData = JSON.stringify(data); if (serializedData !== previousSerializedData.current) { debouncedSave(data); // Trigger save if there's a difference } return () => { debouncedSave.cancel(); }; }, [data, debouncedSave]); return status; }
Version data entries
27 entries across 27 versions & 1 rubygems