Instead of polling you subscribe to receive update from server-side query functions in a Convex deployment. Convex is a database with server-side (db-side? like stored procedures) functions that update reactively.
Instead of polling you subscribe to receive update from server-side query
functions in a Convex deployment. Convex is a database with server-side
(db-side? like stored procedures) functions that update reactively.
New results for all relevant subscriptions are pushed to the client where they
update at the same time so data is never stale and there's no need to callqueryClient.invalidateQueries().
See ./src/example.tsx for a real example. The general
pattern:
1. Create a ConvexClient and ConvexQueryClient. Set the global default
queryKeyHashFn to convexQueryClient.hashFn() and queryFn to
convexQueryClient.queryFn(). Connect the ConvexQueryClient to the React
Query QueryClient.
``ts`
const convexClient = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);
const convexQueryClient = new ConvexQueryClient(convexClient);
const queryClient = new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: convexQueryClient.hashFn(),
queryFn: convexQueryClient.queryFn(),
},
},
});
convexQueryClient.connect(queryClient);
2. Use useQuery() with the convexQuery options factory function called withapi
an object imported from ../convex/_generated/server and the arguments
for this query function. These two form the query key.
`ts`
const { isPending, error, data } = useQuery({
...convexQuery(api.repos.get, { repo: "made/up" }),
gcTime: 10000, // unsubscribe after 10s of no use
});
staleTime is set to Infinity beacuse this data is never stale; it'sgcTime
proactively updated whenever the query result updates on the server. (see
tkdodo's post
for more about this) If you like, customize the to the length of time auseQuery()
query subscription should remain active after all hooks using it
have unmounted.
If you need to use a Convex Action as a query, it won't be reactive; you'll get
all the normal tools from React Query to refetch it.
New query results are pushed from the server, so a staleTime of Infinity
should be used.
Your app will remain subscribed to a query until the gcTime has elapsed. Tune
this for your app: it's usually a good tradeoff to use a value of at least a
couple seconds.
To run this example:
- npm installnpm run dev
-
If you wrap your app in a ConvexProvider you'll be able to use convex hooksuseConvexMutation
like and useConvexAction.:
`tsx`
You can use this mutation function directly or wrap it in a TanStack Query
useMutation:
`ts`
const mutationFn = useConvexMutation(api.board.createColumn);
const { mutate } = useMutation({ mutationFn });
`ts`
const { mutate } = useMutation({
mutationFn: useConvexAction(api.time.getTotal),
});
Note: The example app includes a basic Convex Auth implementation for
reference.
TanStack Query isn't opionated about auth; an auth code might be a an element of
a query key like any other. With Convex it's not necessary to add an additional
key for an auth code; auth is an implicit argument to all Convex queries and
these queries will be retried when authentication info changes.
Convex auth is typically done via JWT: some query functions will fail if
requested before calling convexReactClinet.setAuth() with a function that
provides the token.
Auth setup looks just like it's recommended in
Convex docs, which make use of components that
use native convex hooks. For Clerk, this might look like this: a ClerkProviderConvexProviderWithClerk
for auth, a for the convex client, and aQueryClient.
``
See the Convex Auth docs for setup instructions.
- auth
- paginated queries
- cleanup / unsubscribe in useEffect; something with hot reloading may not be
working right
After cloning this repo run npm i to install dependencies. This package uses
tshy to publish an ESM. If there's ever demand
for a CJS build we can add "cjs" to the "dialects" section of "tshy" config in
the package.json.
To publish an alpha release, update the version in package.json to something
like 0.0.0-alpha.1 and run just rush-pnpm publish --tag alpha.
To publish a regular release, update the version in package.json to something
like 0.1.2 and run just rush-pnpm publish`.