T
TanStack•17mo ago
subsequent-cyan

Select, structuralSharing and 'global' stability

If I run a non-select query twice, the returned data will be identical, globally.
const { data: d1 } = useNonSelectQuery()
const { data: d2 } = useNonSelectQuery()

d1 === d2
const { data: d1 } = useNonSelectQuery()
const { data: d2 } = useNonSelectQuery()

d1 === d2
When I use a query with a select, that reshapes the data (instantiates new variables) this is no longer true. I know that each observer has its own #selectResult and this is why they are no longer identical, but would it be a viable to extend the functionality of memoization (hacky implementation + cleanup on unsub):
// Select data if needed
if (options.select && newState.data !== undefined) {
// Memoize select result
if (
prevResult &&
newState.data === prevResultState?.data &&
options.select === this.#selectFn
) {
data = selectFnStore.get(this.#selectFn) // THIS
} else {
try {
selectFnStore.remove(this.#selectFn) // AND THIS
this.#selectFn = options.select
data = options.select(newState.data)
data = replaceData(prevResult?.data, data, options)
selectFnStore.set(this.#selectFn, data) // AND THAT
this.#selectResult = data
this.#selectError = null
} catch (selectError) {
this.#selectError = selectError as TError
}
}
}
// Select data if needed
if (options.select && newState.data !== undefined) {
// Memoize select result
if (
prevResult &&
newState.data === prevResultState?.data &&
options.select === this.#selectFn
) {
data = selectFnStore.get(this.#selectFn) // THIS
} else {
try {
selectFnStore.remove(this.#selectFn) // AND THIS
this.#selectFn = options.select
data = options.select(newState.data)
data = replaceData(prevResult?.data, data, options)
selectFnStore.set(this.#selectFn, data) // AND THAT
this.#selectResult = data
this.#selectError = null
} catch (selectError) {
this.#selectError = selectError as TError
}
}
}
to memo the selectResult globally based on options.select/#selectFn (and probably structuralSharing too)? I understand that this would require select to be as stable as possible - either static or memoized - or adding a new selectKey prop, but maybe 🙃 ?
3 Replies
manual-pink
manual-pink•17mo ago
Could you please explain what we would gain from this?
extended-salmon
extended-salmon•17mo ago
you can use some global memoization lib like reselect to have the selector result cached globally. We're not gonna do this in query.
subsequent-cyan
subsequent-cyanOP•17mo ago
Alright, thanks.

Did you find this page helpful?