Allows app developers load indexedDB data and keep their component updated whenever the data changes.


npm install react
npm install dexie-react-hooks
npm install dexie@>3.1-alpha


export function useLiveQuery<T, TDefault=undefined> (
  querier: () => Promise<T> | T,
  deps?: any[], // deps argument in useEffect() but defaults to empty array.
  defaultResult?: TDefault // Default value returned while data is loading
) : T | TDefault;

Simple Example

import React from "react";
import Dexie from "dexie";
import { useLiveQuery } from "dexie-react-hooks";

const db = new Dexie('myDB');
  friends: '++id, name, age'

export function OldFriendsList() {
  const friends = useLiveQuery(
    () => db.friends
  if (!friends) return null; // Still loading.
  return <ul>
    { =>
        <li key={}>
          {}, {friend.age}

Enhanced Example

This example shows that…

  • you can observe the result of an arbritary function that queries Dexie
  • you can use a state from a useState() result within your querier function (just need to mention it in the deps array)
  • the component will re-render if the data you are querying change
  • the component will re-render if in-parameter to the query change.
  • the query will change when state change.
import React, { useState } from "react";
import { useLiveQuery } from "dexie-react-hooks";
import { db } from "../db";

export function FriendList() {
  const [maxAge, setMaxAge] = useState(21);

  // Query friends within a certain range decided by state:
  const friends = useLiveQuery(
    () => db.friends.where("age").belowOrEqual(maxAge).sortBy("id"),
    [maxAge] // because maxAge affects query!

  // Example of another query in the same component.
  const friendCount = useLiveQuery(() => db.friends.count());

  // If default values are returned, queries are still loading:
  if (!friends || friendCount === undefined) return null;

  return (
        Your have <b>{friendCount}</b> friends in total.
        Please enter max age:
          onChange={(ev) => setMaxAge(parseInt(, 10))}
        { => (
          <li key={}>
            {}, {friend.age}
              onClick={() =>
                db.friends.where({ id: }).modify((f) => ++f.age)

Open in codesandbox


The expression passed to useLiveQuery() must be a function that returns a promise. If you need to decouple your component from the db, you can provide the querying functions as callbacks instead:

export function FriendList({getFriendCount, getFriendsByAge, onBirthdayClick}) {

  const friendCount = useLiveQuery(getFriendCount);

  const friends = useLiveQuery(
    () => getFriendsByAge(maxAge), [maxAge]

      // And the button's onClick event:
      <button ... onClick={()=>onBirthdayClick(friend)}>...</button>

// ...and implement the callback elsewhere...

function App () {
   const getFriendCount = () => db.friends.count();

   const getFriendsByAge = maxAge =>

   const onBirthdayClick = friend =>
    db.friends.where({ id: }).modify(f => ++f.age);
  return <FriendList
    onBirthdayClick={onBirthdayClick} />;


Another sample using useLiveQuery() on Stackblitz

The sample from this page in CodeSandbox

See also

A blog post about this

Table of Contents