#Is there a way to check if useQuery is loading?
5 messages · Page 1 of 1 (latest)
Hi @dusty path. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Yes, you can check if a Convex useQuery is loading by checking if the returned value is undefined. When useQuery is first mounted or when the query parameters change, it returns undefined until the data is loaded from Convex.
Handling Loading States
The flickering you're experiencing is a common issue with reactive queries. When the query parameters change, useQuery returns undefined while fetching new data, which can cause UI elements to briefly disappear before showing the new results.
const data = useQuery(api.functions.myQuery, { param });
return data === undefined ? "Loading..." : <DisplayData data={data} />;
Solutions to Prevent Flickering
1. Use a Custom Stable Query Hook
You can create a custom hook that maintains the previous query result while loading new data:
import { useRef } from 'react';
import { useQuery } from 'convex/react';
export const useStableQuery = ((query, ...args) => {
const result = useQuery(query, ...args);
const stored = useRef(result);
if (result !== undefined) {
stored.current = result;
}
return stored.current;
}) as typeof useQuery;
This hook will return the previous data while new data is loading, preventing the flickering effect Stack > Help, my app is overreacting!.
2. Enhanced Stable Query with Loading Status
If you need to know the loading state while still showing stable data, you can modify the hook:
import React from 'react';
import { OptionalRestArgsOrSkip, useQuery } from 'convex/react';
import { FunctionReference } from 'convex/server';
export function useStableQuery<Query extends FunctionReference<'query'>>(
query: Query,
...args: OptionalRestArgsOrSkip<Query>
): {data: Query['_returnType'] | undefined; isLoading: boolean} {
const result = useQuery(query, ...args);
const stored = React.useRef(result);
if (result !== undefined) {
stored.current = result;
}
return {data: stored.current, isLoading: result === undefined};
}
This gives you both stable data and loading status [Discord support thread: stable query with status](<https://discord.com/channels/1019350475847499849/1350461175296692327>).
### 3. For Paginated Queries
If you're using pagination, you can create a similar stable hook for paginated queries:
```javascript
import { useRef } from 'react';
import { usePaginatedQuery } from 'convex/react';
export const useStablePaginatedQuery = ((name, ...args) => {
const result = usePaginatedQuery(name, ...args);
const stored = useRef(result);
if (result.status !== 'LoadingMore') {
stored.current = result;
}
return stored.current;
}) as typeof usePaginatedQuery;
This prevents flickering when paginated query parameters change Stack > Help, my app is overreacting!.
4. Using TanStack Query
If you're using TanStack Query with Convex, it provides built-in loading states:
import { useQuery } from "@tanstack/react-query";
import { convexQuery } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
export function App() {
const { data, isPending, error } = useQuery(
convexQuery(api.functions.myQuery, { id: 123 }),
);
return isPending ? "Loading..." : data;
}
This gives you explicit loading states through the isPending property Client > Convex with TanStack Query.