T
TanStack2mo ago
ratty-blush

useLiveQuery optimization: collection or collection options?

Say I just want a simple view on my Tanstack Query Collection (which in on itself is a dependent query). Is it better to create the collection first, memoize it, and then pass that to useLiveQuery, or should I just pass the full createCollection with options to useLiveQuery and it will ensure I don't get a dupe if the options are the same? Just trying to minimize work on re-renders or worse, end up with multiple inconsistent collections. Example: All-In-One
const query = useLiveQuery(
createCollection(
queryCollectionOptions({
queryKey: ['pim', 'eligibleRoles'],
enabled: eligibleRolesQuery.every(q => q.isSuccess),
queryFn: async () => {
return eligibleRolesQuery.flatMap(q => q.data ?? [])
},
queryClient,
getKey: role => role.id,
})
)
)
const query = useLiveQuery(
createCollection(
queryCollectionOptions({
queryKey: ['pim', 'eligibleRoles'],
enabled: eligibleRolesQuery.every(q => q.isSuccess),
queryFn: async () => {
return eligibleRolesQuery.flatMap(q => q.data ?? [])
},
queryClient,
getKey: role => role.id,
})
)
)
vs separate memoized collection
const collection = useMemo(
() => {
const collection = createCollection(
queryCollectionOptions({
queryKey: ['pim', 'eligibleRoles'],
enabled: eligibleRolesQuery.every(q => q.isSuccess),
queryFn: async () => {
return eligibleRolesQuery.flatMap(q => q.data ?? [])
},
queryClient,
getKey: role => role.id,
})
)
return collection
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- avoids recalc when account timestamps change
[queryClient, accountHomeIdHash]
)

const liveQuery = useLiveQuery(collection)
const collection = useMemo(
() => {
const collection = createCollection(
queryCollectionOptions({
queryKey: ['pim', 'eligibleRoles'],
enabled: eligibleRolesQuery.every(q => q.isSuccess),
queryFn: async () => {
return eligibleRolesQuery.flatMap(q => q.data ?? [])
},
queryClient,
getKey: role => role.id,
})
)
return collection
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- avoids recalc when account timestamps change
[queryClient, accountHomeIdHash]
)

const liveQuery = useLiveQuery(collection)
Thanks!
1 Reply
ratty-blush
ratty-blushOP2mo ago
After some experimentation the all-in-one seems to cause a recursion error by passing collection as the parameter directly rather than a query, which is supported in the function overloads but seems to be bugged. This is what I got to work:
const collection = useMemo(
() => {
const collection = createCollection(
queryCollectionOptions({
queryKey: ['pim', 'eligibleRoles'],
enabled: eligibleRolesQuery.every(q => q.isSuccess),
queryFn: async () => {
return eligibleRolesQuery.flatMap(q => q.data ?? [])
},
queryClient,
getKey: role => role.id,
})
)
return collection
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- avoids recalc when account timestamps change
[queryClient, accountHomeIdHash]
)

const liveQuery = useLiveQuery(q => q.from({collection}))
const collection = useMemo(
() => {
const collection = createCollection(
queryCollectionOptions({
queryKey: ['pim', 'eligibleRoles'],
enabled: eligibleRolesQuery.every(q => q.isSuccess),
queryFn: async () => {
return eligibleRolesQuery.flatMap(q => q.data ?? [])
},
queryClient,
getKey: role => role.id,
})
)
return collection
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- avoids recalc when account timestamps change
[queryClient, accountHomeIdHash]
)

const liveQuery = useLiveQuery(q => q.from({collection}))
Not sure if the memoization of createCollection is necessary or not

Did you find this page helpful?