React
To aid integration of PGlite into a React project we have a PGliteProvider
with a corresponding usePGlite
and hooks for the live query plugin.
PGliteProvider
The PGliteProvider
enables you to initiate a PGlite database and pass it to all child components for use with the usePGlite
, useLiveQuery
, and useLiveIncrementalQuery
hooks.
To use it, pass a PGlite instance as the db
property.
import { PGlite } from "@electric-sql/pglite"
import { live } from "@electric-sql/pglite/live"
import { PGliteProvider } from "@electric-sql/pglite-react"
const db = await PGlite.create({
extensions: { live }
})
const App = () => {
// ...
return (
<PGliteProvider db={db}>
// ...
</PGliteProvider>
)
}
usePGlite
You can retrieve the provided PGlite instance using usePGlite
and then query it from within your components.
import { usePGlite } from "@electric-sql/pglite-react"
const MyComponent = () => {
const db = usePGlite()
const insertItem = () => {
db.query("INSERT INTO my_table (name, number) VALUES ('Arthur', 42);")
}
return (
<>
<button onClick={insertItem}
</>
)
}
makePGliteProvider
The makePGliteProvider
function returns a PGliteProvider
component and a usePGlite
hook with the specified type, which enables you to provide a PGlite instance with all added extensions and retain then namespaces and types added to it.
import { PGlite, PGliteInterfaceExtensions } from '@electric-sql/pglite'
import { LiveNamespace } from '@electric-sql/pglite/live'
import { VectorNamespace } from '@electric-sql/pglite/vector'
import { makePGliteProvider } from '@electric-sql/pglite-react'
const { PGliteProvider, usePGlite } = makePGliteProvider<
PGlite &
PGliteInterfaceExtensions<{
live: typeof live
vector: typeof vector
}>
>()
export { PGliteProvider, usePGlite }
useLiveQuery
The useLiveQuery
hook enables you to reactively re-render your component whenever the results of a live query change. It wraps the .live.query()
API.
It has the interface:
function useLiveQuery<T = { [key: string]: unknown }>(
query: string,
params: unknown[] | undefined | null,
): Results<T>
And its arguments are:
- the SQL query
- optional parameters for the query
import { useLiveQuery } from '@electric-sql/pglite-react'
const MyComponent = () => {
const maxNumber = 100
const items = useLiveQuery(`
SELECT *
FROM my_table
WHERE number <= $1
ORDER BY number;
`, [maxNumber])
return (
<>
{
items.map((item) =>
<MyItem item={item} />
)
}
</>
)
}
useLiveQuery.sql
Similarly to how you can use sql``
to to construct SQL queries through string templating, you can do that with useLiveQuery.sql``
for the hook equivalent. See the templating section of the API for more details.
import { useLiveQuery } from '@electric-sql/pglite-react'
const MyComponent = () => {
const maxNumber = 100
const items = useLiveQuery.sql`
SELECT *
FROM my_table
WHERE number <= ${maxNumber}
ORDER BY number;
`
// ...
useLiveIncrementalQuery
The useLiveIncrementalQuery
hook enables you to reactively re-render your component whenever the results of a live query change. It wraps the .live.incrementalQuery()
API, which provides a way to efficiently diff the query results in Postgres.
It has the interface:
function useLiveIncrementalQuery<T = { [key: string]: unknown }>(
query: string,
params: unknown[] | undefined | null,
key: string,
): Results<T>
And its arguments are:
- the SQL query
- optional parameters for the query
- the name of the column to key the diff algorithm on
import { useLiveIncrementalQuery } from '@electric-sql/pglite-react'
const MyComponent = () => {
const maxNumber = 100
const items = useLiveIncrementalQuery(`
SELECT *
FROM my_table
WHERE number <= $1
ORDER BY number;
`, [maxNumber], 'id')
return (
<>
{
items.map((item) =>
<MyItem item={item} />
)
}
</>
)
}