React IndexedDB Hook

2.0.1 · active · verified Wed Apr 22

react-indexed-db-hook provides a simplified interface for interacting with the browser's IndexedDB, exposed as a React Hook. It is a fork of `react-indexed-db` that primarily focuses on a hook-based API for modern React applications. The current stable version is 2.0.1. While it offers a context-based API, the maintainer explicitly states a lack of future support for it, pushing users towards the `useIndexedDB` hook. The library aims to abstract away the complexities of IndexedDB, providing common CRUD operations (getByID, getAll, add, update, delete) through a concise hook interface, making client-side data persistence more accessible in React projects. Its release cadence appears to be feature-driven rather than time-boxed, with updates addressing bugs or adding minor enhancements. Key differentiators include its explicit focus on a modern React hook API and a lightweight abstraction over raw IndexedDB.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to initialize the IndexedDB, use the `useIndexedDB` hook to perform CRUD operations (add, get, update, delete) on an 'items' object store, and display the items in a React component.

import React, { useEffect, useState } from 'react';
import { initDB, useIndexedDB } from 'react-indexed-db-hook';

// 1. Define your DB configuration
export const DBConfig = {
  name: 'MyTestDB',
  version: 1,
  objectStoresMeta: [
    {
      store: 'items',
      storeConfig: { keyPath: 'id', autoIncrement: true },
      storeSchema: [
        { name: 'name', keypath: 'name', options: { unique: false } },
        { name: 'value', keypath: 'value', options: { unique: false } }
      ]
    }
  ]
};

// 2. Initialize the DB once at the application entry point
initDB(DBConfig);

interface Item {
  id?: number;
  name: string;
  value: string;
}

const ItemManager: React.FC = () => {
  const { add, getAll, getByID, update, deleteRecord } = useIndexedDB<Item>('items');
  const [items, setItems] = useState<Item[]>([]);
  const [newItemName, setNewItemName] = useState('');
  const [newItemValue, setNewItemValue] = useState('');
  const [selectedItemId, setSelectedItemId] = useState<number | null>(null);
  const [editItemName, setEditItemName] = useState('');
  const [editItemValue, setEditItemNameValue] = useState('');

  const refreshItems = async () => {
    const allItems = await getAll();
    setItems(allItems);
  };

  useEffect(() => {
    refreshItems();
  }, []);

  const handleAddItem = async () => {
    await add({ name: newItemName, value: newItemValue });
    setNewItemName('');
    setNewItemValue('');
    refreshItems();
  };

  const handleEditSelect = async (id: number) => {
    const item = await getByID(id);
    if (item) {
      setSelectedItemId(id);
      setEditItemName(item.name);
      setEditItemNameValue(item.value);
    }
  };

  const handleUpdateItem = async () => {
    if (selectedItemId) {
      await update({ id: selectedItemId, name: editItemName, value: editItemValue });
      setSelectedItemId(null);
      setEditItemName('');
      setEditItemNameValue('');
      refreshItems();
    }
  };

  const handleDeleteItem = async (id: number) => {
    await deleteRecord(id);
    refreshItems();
  };

  return (
    <div>
      <h1>Items</h1>
      <div>
        <input
          type="text"
          placeholder="Name"
          value={newItemName}
          onChange={(e) => setNewItemName(e.target.value)}
        />
        <input
          type="text"
          placeholder="Value"
          value={newItemValue}
          onChange={(e) => setNewItemValue(e.target.value)}
        />
        <button onClick={handleAddItem}>Add Item</button>
      </div>

      {selectedItemId && (
        <div>
          <h3>Edit Item (ID: {selectedItemId})</h3>
          <input
            type="text"
            value={editItemName}
            onChange={(e) => setEditItemName(e.target.value)}
          />
          <input
            type="text"
            value={editItemValue}
            onChange={(e) => setEditItemNameValue(e.target.value)}
          />
          <button onClick={handleUpdateItem}>Update Item</button>
          <button onClick={() => setSelectedItemId(null)}>Cancel</button>
        </div>
      )}

      <ul>
        {items.map((item) => (
          <li key={item.id}>
            {item.name}: {item.value}
            <button onClick={() => handleEditSelect(item.id!)}>Edit</button>
            <button onClick={() => handleDeleteItem(item.id!)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default ItemManager;

view raw JSON →