Working with data
Infinite Queries
It is a common pattern to show users a long list of items that gets larger as they interact. Instant supports this pattern with the useInfiniteQuery hook.
The useInfiniteQuery hook is designed to work just like the useQuery hook. You make the same kind of queries and it returns the same kind of data. But now you get a canLoadNextPage variable, and a loadNextPage function to load more items.
#Example
This example demonstrates a typical social media feed where the newest posts are at the top.
import { init } from '@instantdb/react';import { db } from "../db"import { Post } from "../components/Post"function HomePage() {const { data, canLoadNextPage, loadNextPage, isLoading, error } =db.useInfiniteQuery({posts: {$: {limit: 50, // Load 50 posts at a timeorder: {createdAt: 'desc',},},},});if (isLoading) {return <div>Loading...</div>;}if (error) {return <div>Error: {error.message}</div>;}return (<div>{data.posts.map((post) => (<Post key={post.id} post={post} />))}{canLoadNextPage && (<button onClick={loadNextPage}>Load More</button>)}</div>);}
Any new posts that get created will automatically appear at the top, and as the user scrolls, the loadNextPage can load older posts as needed.
#Reactivity
Just like useQuery, all data returned is fully reactive. Updating and deleting items will react immediately. New items added to the "start" of the query will show up automatically as well as items anywhere in the middle. Items that would be ordered at the very end of the results will show up if the limit for that page has not yet been reached.
For example, with {todos: {$: {limit: 20, order: createdAt: "asc"}}} (showing oldest todos first)
If there are already 19 todos in the database, an additional todo getting created will show up in the result automatically, and the next todo after that will set "canLoadNextPage" to true, requiring the loadNextPage function to be called. When the new page is added, any newly created todos will show up at the end automatically until 40 total todos are shown.
Changing any part of the query will result in a full reset of all data, returning back to a state with only one page loaded.
#Vanilla JS
The @instantdb/core library also supports making infinite queries with the same syntax as db.subscribeQuery().
Example:
const { unsubscribe, loadNextPage } = db.subscribeInfiniteQuery({posts: {$: {limit: 20, // Load 20 posts at a timeorder: {createdAt: 'desc',},},},},(resp) => {console.log('Posts: ', resp.data.posts);console.log('Can Load More ?', resp.canLoadNextPage);},);