#How do I prevent unneeded queries in React Native?
5 messages · Page 1 of 1 (latest)
Hi @nova wave. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Convex is designed to re-run queries whenever the underlying data they read changes, so the main way to “prevent unneeded queries” is to:
- Stop subscribing when you don’t need reactivity, and/or
- Keep more state on the client instead of in a reactive query.
From the knowledge sources, there are two concrete patterns you can use:
1. Keep user data in client state instead of a live query
If the user data is mostly “local UI state” and you only care about the server when it changes on another device, you can:
- Fetch it once with
convex.query(...)(non-reactive, one-shot) instead ofuseQuery. - Store it in React state and mutate that state locally.
- Only write back to Convex when you actually want to persist a change.
This is the same pattern suggested for a “Tinder-style” UI where reactivity caused too many invalidations: they switched from useQuery to useConvex().query(...) plus local state so the list wouldn’t re-run on every mutation. [Batch ops thread]
// React Native example pattern
const convex = useConvex();
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
convex.query(api.users.getCurrentUser).then(setUser);
}, []);
const updateLocalOnly = (partial: Partial<User>) => {
setUser(prev => (prev ? { ...prev, ...partial } : prev));
};
const persistToServer = async () => {
if (!user) return;
await convex.mutation(api.users.updateUser, { user });
};
This avoids a live subscription entirely; the query only runs when you call it.
2. Use reactive queries only for the “shared” part
If you still want real-time sync across devices, keep the shared fields in Convex and:
- Use
useQueryonly for those fields that must stay in sync across devices. [Realtime db] - Keep purely local UI state (e.g. transient form edits, filters, in-progress changes) in React state, not in Convex.
This is the same idea as “isolating frequently changing data” into separate documents so only the queries that care about it are invalidated. [Queries that scale]
3. When you do want reactivity but less churn
If your issue is more about “flashing/loading” than bandwidth, you can wrap useQuery in a custom hook that keeps the last non-undefined value and skips the intermediate loading state. [Help my app is overreacting]
// useStableQuery.ts
import { useRef } from "react";
import { useQuery } from "convex/react";
export const useStableQuery = ((name, ...args) => {
const result = useQuery(name, ...args);
const stored = useRef(result);
if (result !== undefined) stored.current = result;
return stored.current;
}) as typeof useQuery;
This doesn’t reduce the number of server re-runs, but it can make the UX smoother.
If you can share how you’re currently fetching that user (e.g. useQuery vs convex.query), I can map one of these patterns directly onto your code.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@nova wave Kapa.ai is still learning and improving, please let me know how I did by reacting below.