MCPcopy Index your code
hub / github.com/TanStack/db / useLiveQuery

Function useLiveQuery

packages/react-db/src/useLiveQuery.ts:316–565  ·  view source on GitHub ↗
(
  configOrQueryOrCollection: any,
  deps: Array<unknown> = [],
)

Source from the content-addressed store, hash-verified

314
315// Implementation - use function overloads to infer the actual collection type
316export function useLiveQuery(
317 configOrQueryOrCollection: any,
318 deps: Array<unknown> = [],
319) {
320 // Check if it's already a collection by checking for specific collection methods
321 const isCollection =
322 configOrQueryOrCollection &&
323 typeof configOrQueryOrCollection === `object` &&
324 typeof configOrQueryOrCollection.subscribeChanges === `function` &&
325 typeof configOrQueryOrCollection.startSyncImmediate === `function` &&
326 typeof configOrQueryOrCollection.id === `string`
327
328 // Use refs to cache collection and track dependencies
329 const collectionRef = useRef<Collection<object, string | number, {}> | null>(
330 null,
331 )
332 const depsRef = useRef<Array<unknown> | null>(null)
333 const configRef = useRef<unknown>(null)
334
335 // Use refs to track version and memoized snapshot
336 const versionRef = useRef(0)
337 const snapshotRef = useRef<{
338 collection: Collection<object, string | number, {}> | null
339 version: number
340 } | null>(null)
341
342 // Check if we need to create/recreate the collection
343 const needsNewCollection =
344 !collectionRef.current ||
345 (isCollection && configRef.current !== configOrQueryOrCollection) ||
346 (!isCollection &&
347 (depsRef.current === null ||
348 depsRef.current.length !== deps.length ||
349 depsRef.current.some((dep, i) => dep !== deps[i])))
350
351 if (needsNewCollection) {
352 if (isCollection) {
353 // Warn when passing a collection directly with on-demand sync mode
354 // In on-demand mode, data is only loaded when queries with predicates request it
355 // Passing the collection directly doesn't provide any predicates, so no data loads
356 const syncMode = (
357 configOrQueryOrCollection as { config?: { syncMode?: string } }
358 ).config?.syncMode
359 if (syncMode === `on-demand`) {
360 console.warn(
361 `[useLiveQuery] Warning: Passing a collection with syncMode "on-demand" directly to useLiveQuery ` +
362 `will not load any data. In on-demand mode, data is only loaded when queries with predicates request it.\n\n` +
363 `Instead, use a query builder function:\n` +
364 ` const { data } = useLiveQuery((q) => q.from({ c: myCollection }).select(({ c }) => c))\n\n` +
365 `Or switch to syncMode "eager" if you want all data to sync automatically.`,
366 )
367 }
368 // It's already a collection, ensure sync is started for React hooks
369 configOrQueryOrCollection.startSyncImmediate()
370 collectionRef.current = configOrQueryOrCollection
371 configRef.current = configOrQueryOrCollection
372 } else {
373 // Handle different callback return types

Callers 15

useLiveSuspenseQueryFunction · 0.90
useLiveInfiniteQueryFunction · 0.90
AuthenticatedLayoutFunction · 0.90
ProjectPageFunction · 0.90
QueryPageFunction · 0.90
TrailBasePageFunction · 0.90
ElectricPageFunction · 0.90
PersistedTodoDemoFunction · 0.90
TodoDemoFunction · 0.90

Calls 6

startSyncImmediateMethod · 0.80
fromMethod · 0.80
subscribeChangesMethod · 0.45
unsubscribeMethod · 0.45
entriesMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…