StructuralSharing<TQueryData> typedef

StructuralSharing<TQueryData> = TQueryData Function(TQueryData? previous, TQueryData next)

Decides what is written into the cache when new data arrives, given what was there before.

Unset, replaceEqualDeep applies: data that is deep-equal to the previous data keeps the previous instance, so an unchanged refetch notifies nobody for unchanged data alone. Lists are shared element by element; maps and sets are compared deeply and shared whole, while typed models use their own == (or StructurallyShareable). Set this to noStructuralSharing() (noStructuralSharing) to turn sharing off, or to a function of your own to reconcile typed models yourself. TanStack Query spells the opt-out structuralSharing: false.

QueryOptions<Board>(
  queryKey: QueryKey(['board']),
  queryFn: fetchBoard,
  structuralSharing: (previous, next) =>
      previous != null && previous.version == next.version
          ? previous
          : next,
);

A hook governs the cache write and unselected placeholder data. A select's output goes through replaceEqualDeep instead, because a hook typed on the raw data cannot be handed a selection of another type. (TanStack Query calls its hook on the selected value as well.) Only noStructuralSharing() turns the selection's sharing off as well: a hook that does share, deeply or in its own way, leaves the selection at the default. After removing a selector, an unselected placeholder receives no previous raw value from that selection.

previous is null when nothing has been cached yet. With a nullable TQueryData the hook cannot tell that apart from a previous value that was null; a hook that needs the distinction reads query.state.hasData instead.

Implementation

typedef StructuralSharing<TQueryData> = TQueryData Function(
    TQueryData? previous, TQueryData next);