npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-indexed-db

v2.0.1

Published

React wrapper to IndexedDB database.

Downloads

4,239

Readme

react-indexed-db-hook

react-indexed-db-hook is forked from react-indexed-db. This library is a wrapper around the browser's IndexedDB database in an "easier to use" React Hook.

Installation

npm install react-indexed-db-hook

Creating the DB

You can choose to work with the indexed db as an context or to use it as a hook. However, I don't plan on supporting the context, but it's there if you want it.

To use it as a hook

  • First initialized your DB before to be able to use the hooks inside other components:
//DBConfig.js|tsx

export const DBConfig = {
  name: "MyDB",
  version: 1,
  objectStoresMeta: [
    {
      store: "people",
      storeConfig: { keyPath: "id", autoIncrement: true },
      storeSchema: [
        { name: "name", keypath: "name", options: { unique: false } },
        { name: "email", keypath: "email", options: { unique: false } },
      ],
    },
  ],
};
//App.js|tsx

import React from "react";
import { DBConfig } from "./DBConfig";
import { initDB } from "react-indexed-db-hook";

initDB(DBConfig);

const App: React.FC = () => {
  return <div>...</div>;
};

To use it as a context:

  • First you have to declare inside <IndexedDB></IndexedDB> all the components you want to be able access the DB:
import { IndexedDB } from "react-indexed-db-hook";
import PanelExample from "./Panel";

function App() {
  return (
    <IndexedDB
      name="MyDB"
      version={1}
      objectStoresMeta={[
        {
          store: "people",
          storeConfig: { keyPath: "id", autoIncrement: true },
          storeSchema: [
            { name: "name", keypath: "name", options: { unique: false } },
            { name: "email", keypath: "email", options: { unique: false } },
          ],
        },
      ]}
    >
      <Panel />
    </IndexedDB>
  );
}

Accessing and working with the DB

  • In any component inside this context or in an app using the hooks after creating the DB you can consume it like bellow:
// Context
import { AccessDB } from 'react-indexed-db-hook';

export default function PanelExample() {
  return (
    <AccessDB objectStore="people">
      {db => {
        console.log('MyDB: ', db);
        return <div>{JSON.stringify(db)}</div>;
      }}
    </AccessDB>
  );
}

// Hooks
import { useIndexedDB } from 'react-indexed-db-hook';

export default function PanelExample() {
  const db = useIndexedDB('people');

  return (<div>{JSON.stringify(db)}</div>);
}

getByID(id)

It returns the object that is stored in the objectStore by its id. getByID returns a promise that is resolved when we have the object or rejected if an error occurred.

Usage example:

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB objectStore="people">
  {({ getById }) => {
    const [person, setPerson] = useState(null);
    getById("people", 1).then(
      (personFromDB) => {
        setPerson(personFromDB);
      },
      (error) => {
        console.log(error);
      },
    );
    return <div>{person}</div>;
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function ByID() {
  const { getByID } = useIndexedDB("people");
  const [person, setPerson] = useState();

  useEffect(() => {
    getById(1).then((personFromDB) => {
      setPerson(personFromDB);
    });
  }, []);

  return <div>{person}</div>;
}

getAll()

It returns an array of all the items in the given objectStore. getAll returns a promise that is resolved when we have the array of items or rejected if an error occurred.

Usage example:

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB objectStore="people">
  {({ getAll }) => {
    const [persons, setPersons] = useState(null);
    getAll().then(
      (peopleFromDB) => {
        setPersons(peopleFromDB);
      },
      (error) => {
        console.log(error);
      },
    );
    return (
      <div>
        {personsFromDB.map((person) => (
          <span>{person}</span>
        ))}
      </div>
    );
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function ShowAll() {
  const { getAll } = useIndexedDB("people");
  const [persons, setPersons] = useState();

  useEffect(() => {
    getAll().then((personsFromDB) => {
      setPersons(personsFromDB);
    });
  }, []);

  return (
    <div>
      {personsFromDB.map((person) => (
        <span>{person}</span>
      ))}
    </div>
  );
}

getByIndex(indexName, key)

It returns an stored item using an objectStore's index. The first parameter is the index and the second is the item to query. getByIndex returns a promise that is resolved when the item successfully returned or rejected if an error occurred.

Usage example:

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB objectStore="people">
  {({ getByIndex }) => {
    const [person, setPerson] = useState(null);
    getByIndex("name", "Dave").then(
      (personFromDB) => {
        setPerson(peopleFromDB);
      },
      (error) => {
        console.log(error);
      },
    );
    return <div>{person}</div>;
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function ByIndex() {
  const { getByIndex } = useIndexedDB("people");
  const [person, setPerson] = useState();

  useEffect(() => {
    getByIndex("name", "Dave").then((personFromDB) => {
      setPerson(peopleFromDB);
    });
  }, []);
  return <div>{person}</div>;
}

add(value, key)

It Adds to the given objectStore the key and value pair. The firt parameter is the value and the second is the key (if not auto-generated). add returns a promise that is resolved when the value was added or rejected if an error occurred.

Usage example (add without a key since it's configured to be auto generated):

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB objectStore="people">
  {({ add }) => {
    const handleClick = () => {
      add({ name: "name", email: "email" }).then(
        (event) => {
          console.log("ID Generated: ", event.target.result);
        },
        (error) => {
          console.log(error);
        },
      );
    };

    return <button onClick={handleClick}>Add</button>;
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function AddMore() {
  const { add } = useIndexedDB("people");
  const [person, setPerson] = useState();

  const handleClick = () => {
    add({ name: "name", email: "email" }).then(
      (event) => {
        console.log("ID Generated: ", event.target.result);
      },
      (error) => {
        console.log(error);
      },
    );
  };

  return <button onClick={handleClick}>Add</button>;
}

update(value, key?)

It updates the given value in the objectStore. The first parameter is the value to update and the second is the key (if there is no key don't provide it). update returns a promise that is resolved when the value was updated or rejected if an error occurred.

Usage example (update without a key):

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB objectStore="people">
  {({ update }) => {
    return (
      <button
        onClick={() => {
          update({ id: 3, name: "NewName", email: "NewEmail" }).then(
            () => {
              // Do something after update
            },
            (error) => {
              console.log(error);
            },
          );
        }}
      >
        Update
      </button>
    );
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function Edit() {
  const { update } = useIndexedDB("people");
  const [person, setPerson] = useState();

  const handleClick = () => {
    update({ id: 3, name: "NewName", email: "NewNEmail" }).then((event) => {
      alert("Edited!");
    });
  };

  return <button onClick={handleClick}>Update</button>;
}

delete(key)

deletes the object that correspond with the key from the objectStore. The first parameter is the key to delete. delete returns a promise that is resolved when the value was deleted or rejected if an error occurred.

Usage example:

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB objectStore="people">
  {({ deleteRecord }) => {
    const handleClick = () => {
      deleteRecord(3).then((event) => {
        alert("Deleted!");
      });
    };
    return <button onClick={handleClick}>Delete</button>;
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function Delete() {
  const { deleteRecord } = useIndexedDB("people");

  const handleClick = () => {
    deleteRecord(3).then((event) => {
      alert("Deleted!");
    });
  };

  return <button onClick={handleClick}>Delete</button>;
}

openCursor(cursorCallback, keyRange)

It opens an objectStore cursor to enable iterating on the objectStore. The first parameter is a callback function to run when the cursor succeeds to be opened and the second is optional IDBKeyRange object. openCursor returns a promise that is resolved when the cursor finishes running or rejected if an error occurred.

Usage example:

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB objectStore="people">
  {({ openCursor }) => {
    const handleClick = () => {
      openCursor((evt) => {
        var cursor = evt.target.result;
        if (cursor) {
          console.log(cursor.value);
          cursor.continue();
        } else {
          console.log("Entries all displayed.");
        }
      }, IDBKeyRange.bound("A", "F"));
    };
    return <button onClick={handleClick}>Run cursor</button>;
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function Open() {
  const { openCursor } = useIndexedDB("people");

  const handleClick = () => {
    openCursor((evt) => {
      var cursor = evt.target.result;
      if (cursor) {
        console.log(cursor.value);
        cursor.continue();
      } else {
        console.log("Entries all displayed.");
      }
    }, IDBKeyRange.bound("A", "F"));
  };

  return <button onClick={handleClick}>Run cursor</button>;
}

clear()

It clears all the data in the objectStore. clear returns a promise that is resolved when the objectStore was cleared or rejected if an error occurred.

Usage example:

// Context
import { AccessDB } from "react-indexed-db-hook";

<AccessDB>
  {({ clear }) => {
    const handleClick = () => {
      clear().then(() => {
        alert("All Clear!");
      });
    };
    return <button onClick={handleClick}>Clear All</button>;
  }}
</AccessDB>;

// Hooks
import { useIndexedDB } from "react-indexed-db-hook";

function ClearAll() {
  const { clear } = useIndexedDB("people");

  const handleClick = () => {
    clear().then(() => {
      alert("All Clear!");
    });
  };

  return <button onClick={handleClick}>Clear All</button>;
}

TODO

  • [ ] Improve this documentation
  • [x] Implement Hooks const {getAll, add ...} = useIndexedDB({name, version, dbSchema?})
  • [ ] Handle getAll() perfomance issue regarding re-render
  • [ ] Implement examples/Demos
  • [x] Remove Webpack
  • [ ] Add automated tests

License

Released under the terms of the MIT License.