织梦CMS - 轻松建站从此开始!

欧博ABG官网-欧博官方网址-会员登入

How to Efficiently Poll for Data with ReaDG游戏ct Qu

时间:2025-10-12 20:21来源: 作者:admin 点击: 3 次
I have a database collection that can be updated by a large number of users in real-time. Users need to be able to see updates from other members, but

I have a database collection that can be updated by a large number of users in real-time. Users need to be able to see updates from other members, but the collection is large, so re-downloading the entire collection every time is massively inefficient/expensive.

Every document has a updateTime timestamp. Given this, what I want to do is poll for updated data as needed (either on component mount or at other frequencies) and merge that into the data already stored in cache with ReactQuery (using persistClientQuery).

I'm new to ReactQuery, so I'm wondering if there's a more efficient approach to than the one I'm using here, where I use React Query's useInfiniteQuery hook with the newest updateTime as the nextPageParam:

The query itself:

export function useTalentWithStore() { const queryClient = useQueryClient(); const query = useInfiniteQuery<Talent[]>({ queryKey: ['talent'], getNextPageParam: (lastPage, allPages) => { const data = allPages.flat(); // Use the newest document's updateTime as the next page param const times = data.map((tal) => tal?.docMeta?.updateTime); if (data.length) { const max = Math.max(...times as any); return new Date(max); } return undefined; }, queryFn: async ({ pageParam }) => { let talentQuery: firebase.firestore.CollectionReference<firebase.firestore.DocumentData> | firebase.firestore.Query<firebase.firestore.DocumentData> = firestore.collection("talent"); // If the there's a page param, just get documents updated since then, otherwise, get everything if (pageParam) { talentQuery = talentQuery.where("docMeta.updateTime", ">", pageParam); } let talentSnapshot = await talentQuery.get(); const talentUpdates: Talent[] = talentSnapshot.docs.map((doc) => { return { id: doc.id, ...doc.data() } }); return talentUpdates; }, staleTime: Infinity, }); // Combine new data with any old data, and return a flat object const flatData = useMemo<Talent[] | undefined>(() => { const oldData = query.data?.pages?.[0] || []; const newData = query.data?.pages?.[1] || []; const combinedData: Talent[] = []; if (oldData) { combinedData.push(...oldData); } for (const tal of newData) { const idx: number = combinedData.findIndex((t) => t.id === tal.id); if (idx >= 0) { combinedData[idx] = tal; } else { combinedData.push(tal); } } // If there's any old data, flush it out and replace it with the combined new data if (oldData.length) { queryClient.setQueryData(['talent'], (data: any) => ({ pages: [combinedData], pageParams: query.data?.pageParams, })); } return combinedData; }, [query.data, queryClient]); return { ...query, flatData }; }

Example Usage:

const talentQuery = useTalentWithStore(); const talent = talentQuery.flatData; const [fetchedOnMount, setFetchedOnMount] = useState(false); useEffect(() => { if (!fetchedOnMount && !talentQuery.isFetching) { console.log(`Fetching New Talent`, !fetchedOnMount && !talentQuery.isFetching); talentQuery.fetchNextPage(); } setFetchedOnMount(true); }, [talentQuery, fetchedOnMount]);

Is all this really necessary, or does ReactQuery support this functionality natively?

If not, are there other approaches I should consider here or pitfalls I need to watch out for?

(Note: While this code uses Firestore, for various reasons, I don't want to use Firestore's real-time updates here)

(责任编辑:)
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:
发布者资料
查看详细资料 发送留言 加为好友 用户等级: 注册时间:2025-10-14 07:10 最后登录:2025-10-14 07:10
栏目列表
推荐内容