T
TanStack2y ago
sensitive-blue

Best practice for selecting a value from a useQuery that returns array

I have a query that returns an array of groups called useGroups
export const groupQuery = queryOptions({
queryKey: ['groups'],
staleTime: 1000,
queryFn: () => {
const groups = db.query.groups.findMany().sync()
return groups || null
},
})

export const useGroups = (overrideOptions?: Omit<typeof groupQuery, 'queryFn' | 'queryKey'>) => {
const queryClient = useQueryClient(xmtpQueryClient)

const { data: groups, ...rest } = useQuery({ ...groupQuery, ...overrideOptions }, queryClient)

return { groups, ...rest }
}
export const groupQuery = queryOptions({
queryKey: ['groups'],
staleTime: 1000,
queryFn: () => {
const groups = db.query.groups.findMany().sync()
return groups || null
},
})

export const useGroups = (overrideOptions?: Omit<typeof groupQuery, 'queryFn' | 'queryKey'>) => {
const queryClient = useQueryClient(xmtpQueryClient)

const { data: groups, ...rest } = useQuery({ ...groupQuery, ...overrideOptions }, queryClient)

return { groups, ...rest }
}
I am currently doing this
const useGroup = ({
topic,
...opts
}: { topic: string } & Omit<Parameters<typeof useGroups>[0], 'select'>) => {
const { groups: group, ...rest } = useGroups({
...opts,
select(data) {
return data.find((group) => group.topic === topic)
},
})

return { group, ...rest }
}
const useGroup = ({
topic,
...opts
}: { topic: string } & Omit<Parameters<typeof useGroups>[0], 'select'>) => {
const { groups: group, ...rest } = useGroups({
...opts,
select(data) {
return data.find((group) => group.topic === topic)
},
})

return { group, ...rest }
}
Typescript doesn't like the select since it isn't returning the same type. Is it better to just use a useMemo?
const useGroup = ({topic}: { topic: string }) => {
const { groups } = useGroups()

const group = useMemo(() => {
return groups?.find((group) => group.topic === topic)
}, [groups, topic])

return { group }
}
const useGroup = ({topic}: { topic: string }) => {
const { groups } = useGroups()

const group = useMemo(() => {
return groups?.find((group) => group.topic === topic)
}, [groups, topic])

return { group }
}
Or should I just create another query altogether and go straight to the database again. This isn't a big issue since the database is actually a local sqlite so no network requests are being made.
2 Replies
constant-blue
constant-blue2y ago
select is right but you need a type parameter on useGroups https://x.com/tkdodo/status/1657026702512467970
sensitive-blue
sensitive-blueOP2y ago
awesome thanks very much back so quick !

Did you find this page helpful?