typescriptadvanced

useIndexedDB Hook

Simple IndexedDB wrapper hook for persistent client-side storage with get, set, and delete.

typescript
import { useCallback, useEffect, useRef } from 'react';

function openDB(name: string, store: string): Promise<IDBDatabase> {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(name, 1);
    request.onupgradeneeded = () => {
      request.result.createObjectStore(store);
    };
    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
}

export function useIndexedDB(dbName: string, storeName: string) {
  const dbRef = useRef<IDBDatabase | null>(null);

  useEffect(() => {
    openDB(dbName, storeName).then(db => { dbRef.current = db; });
    return () => { dbRef.current?.close(); };
  }, [dbName, storeName]);

  const get = useCallback(<T>(key: string): Promise<T | undefined> => {
    return new Promise((resolve, reject) => {
      const tx = dbRef.current!.transaction(storeName, 'readonly');
      const req = tx.objectStore(storeName).get(key);
      req.onsuccess = () => resolve(req.result);
      req.onerror = () => reject(req.error);
    });
  }, [storeName]);

  const set = useCallback((key: string, value: unknown): Promise<void> => {
    return new Promise((resolve, reject) => {
      const tx = dbRef.current!.transaction(storeName, 'readwrite');
      const req = tx.objectStore(storeName).put(value, key);
      req.onsuccess = () => resolve();
      req.onerror = () => reject(req.error);
    });
  }, [storeName]);

  const remove = useCallback((key: string): Promise<void> => {
    return new Promise((resolve, reject) => {
      const tx = dbRef.current!.transaction(storeName, 'readwrite');
      const req = tx.objectStore(storeName).delete(key);
      req.onsuccess = () => resolve();
      req.onerror = () => reject(req.error);
    });
  }, [storeName]);

  return { get, set, remove };
}

Use Cases

  • Offline data storage
  • Caching large datasets

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.