Last active
March 1, 2024 20:01
-
-
Save maxencehenneron/28e58663a96d7e2c38e0dffcc98f8673 to your computer and use it in GitHub Desktop.
Defines a custom React hook useReactiveQuery that rerenders a component when the result of a SQLite query changes. It's designed to work with the drizzle-orm and expo-sqlite libraries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState } from "react"; | |
import { AnySQLiteTable, getTableConfig } from "drizzle-orm/sqlite-core"; | |
import { addDatabaseChangeListener } from "expo-sqlite/next"; | |
import { SQLiteSyncRelationalQuery } from "drizzle-orm/sqlite-core/query-builders/query"; | |
/** | |
* A helper hook that rerenders the component when the result of a query changes | |
* @param query the query to run | |
* @param dependencies the tables that the query depends on | |
* @param rowId the row id to watch for changes | |
* @returns the result of the query (sync) | |
*/ | |
export default function useReactiveQuery< | |
TResult, | |
>( | |
query: SQLiteSyncRelationalQuery<TResult>, | |
dependencies: AnySQLiteTable[], | |
rowId?: TResult extends any[] ? never : number | |
) { | |
const [result, setResult] = useState<TResult>(); | |
useEffect(() => { | |
setResult(query.sync()); | |
const tableNames = dependencies.map((table) => { | |
return getTableConfig(table).name; | |
}); | |
const subscription = addDatabaseChangeListener((change) => { | |
if (rowId !== undefined) { | |
// If the change is to the table and row we are watching | |
if (change.tableName === tableNames[0] && change.rowId === rowId) { | |
setResult(query.sync()); | |
} | |
return; | |
} | |
// If the change is to a table we are watching | |
if (tableNames.includes(change.tableName)) { | |
setResult(query.sync()); | |
} | |
}); | |
return () => { | |
subscription.remove(); | |
} | |
}, []); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment