Docs
CR-SQLite
JS & The Browser
ReactJS

React

To get started with React quickly, scaffold a new project with npm create @vlcn.io@latest your-app-name. Check out main.tsx (opens in a new tab) and App.tsx (opens in a new tab) from the scaffold.

The react integration is provided by the @vlcn.io/react (opens in a new tab) package and centers around:

  1. A useQuery hook that allows you to subscribe to a query and get the data in your component.
  2. A DBProvider (opens in a new tab) to provide one or more databases to your component tree and kick off sync.

Installation

Install:

> npm install @vlcn.io/react @vlcn.io/rx-tbl

Import:

import { useQuery } from "@vlcn.io/react";
import tblrx from "@vlcn.io/rx-tbl";

API

useQuery

type QueryData<T> = {
  readonly loading: boolean;
  readonly error?: Error;
  readonly data: T;
};
 
type CtxAsync = {
  readonly db: DBAsync;
  readonly rx: TblRx;
};
 
function useQuery<R, M = R[]>(
  ctx: CtxAsync,
  query: SQL<R>,
  bindings?: any[],
  postProcess?: (rows: R[]) => M
): QueryData;

Params:

  • ctx - The context object that contains the database and rx-tbl instance.
  • query - The query to run.
  • bindings - The bindings to use for the query (optional)
  • postProcess - A function to post process the data (optional)

Usage:

function MyComponent({ctx}) {
  const { data, loading, error } = useQuery(ctx, "SELECT * FROM users WHERE country = ?", ["NZ"]);
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (
    <ul>
      {data.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

first

Returns the first element of an array or undefined if the array is empty. Useful for queries that return a single row.

function first<T>(data: T[]): T | undefined;

Usage:

const countRow = useQuery(ctx, "SELECT count(*) as c FROM users", null, first).data;
const count = countRow?.c;

firstPick

Returns the first column of the first element of an array or undefined if the array is empty. Useful for queries that return a single row and a single column.

function firstPick<T>(data: any[]): T | undefined;

Usage:

const count = useQuery(ctx, "SELECT count(*) FROM users", null, firstPick).data;
// count is a number

pick

Pick the value of the first column of each row. Useful for queries that return a single column.

function pick<T extends any, R>(data: T[]): R[];

Usage:

const names = useQuery(ctx, "SELECT name FROM users", null, pick).data;
// names is a string[]

Live Example

Below is a live notebook style example. You can modify code in any cell and press shift + enter to run it. Sharing variables between cells is done via provide and use statements. Given we're running everything natively in the browser (no babel or esbuild compilation step), we use htm (opens in a new tab) to write JSX-like syntax.

A cool thing about cr-sqlite is that you get cross-tab sync for free! Open this page in many tabs and interact with the todo widget at the bottom to check it out.

Let's import the cr-sqlite wasm bundle and create a database with a basic schema.

Now we'll write the react component for our todo list.

Lastly, we'll render the component to the page.