TanStackT
TanStackโ€ข2y agoโ€ข
3 replies
opposite-copper

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

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
        }
      }
    }

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 ๐Ÿ™ƒ ?
Was this page helpful?