T
TanStack8mo ago
equal-aqua

How to handle when query depends on a non string/JSON serializable object reference?

I am not fetching any API external data, I am using React Query as an async state manager in one of my projects. A specific query depends on many other object references to be transformed and be available in the shape I want. These other object are very large, and some of them are not JSON serializable. I would like a query key that doesnt parse all its content to string, but instead use the object reference as the comparing subject. Since the query key relies on string serializable variables, I hashed the references. I put together something like this. It got better to read in the query devtools aswell.
class ObjectHasher {
static referenceToHash = new WeakMap()

static getHash(obj: any) {
const found = this.referenceToHash.get(obj)
if (found) return found

const hash = randomString()
this.referenceToHash.set(obj, hash)
return hash
}

static getReference(hash: string) {
return this.referenceToHash.get(hash)
}
}

function App() {
const {} = useQuery({
queryKey: [userId, ObjectHasher.getHash(largeObject)] as const, // <-- this turns into a string
queryFn: ctx => {
const [userId, hash] = ctx.queryKey
const reference = ObjectHasher.getReference(hash) // <-- then I get it back later

...
},
})
}
class ObjectHasher {
static referenceToHash = new WeakMap()

static getHash(obj: any) {
const found = this.referenceToHash.get(obj)
if (found) return found

const hash = randomString()
this.referenceToHash.set(obj, hash)
return hash
}

static getReference(hash: string) {
return this.referenceToHash.get(hash)
}
}

function App() {
const {} = useQuery({
queryKey: [userId, ObjectHasher.getHash(largeObject)] as const, // <-- this turns into a string
queryFn: ctx => {
const [userId, hash] = ctx.queryKey
const reference = ObjectHasher.getReference(hash) // <-- then I get it back later

...
},
})
}
2 Replies
continuing-cyan
continuing-cyan8mo ago
You can provide your own queryKeyHashFn, and you can set it as a default option for all queries
equal-aqua
equal-aquaOP8mo ago
Helpful, Thank you!

Did you find this page helpful?