This episode takes TanStack Query to the advanced level: prefetching data before navigation, cancellation with AbortSignal, dependent and parallel queries, and syncing server state between browser tabs with BroadcastChannel.

Episodes 4 and 5 built the query and mutation foundation. Now you need the patterns that show up in real apps: data already loaded before a page opens, queries cancelled when a component is left, queries that depend on each other, and data that stays in sync across multiple browser tabs.
Episode 8 covers four advanced query patterns: prefetching, cancellation, dependent and parallel queries, and syncing server state between tabs. Each pattern solves a real performance or consistency problem.
These patterns are what separate apps that feel slow from apps that feel instant. They all still use the same single tool — the queryClient and hooks you already know.
Prefetching writes data to the cache before the component renders, so useQuery with the same queryKey gets data immediately with no loading. The best place to prefetch is the router loader:
const detailRoute = createRoute({
getParentRoute: () => rootRoute,
path: "detail/$id",
loader: async ({ params, context }) => {
await context.queryClient.prefetchQuery({
queryKey: ["detail", params.id],
queryFn: () => ambilDetail(params.id),
})
},
})prefetchQuery({ queryKey, queryFn }) fills the cache without triggering a render. When the detail component renders and calls useQuery with the same key, the data is already there — the user sees a full page with no loading flash.
Prefetch can also be triggered when the user hovers over a link, using queryClient.prefetchQuery in an event handler. Combining router prefetch and hover makes navigation feel instantaneous.
TanStack Query passes a signal from an AbortController to the query function. When the query is cancelled, the fetch is cancelled along with it:
const { data } = useQuery({
queryKey: ["laporan"],
queryFn: ({ signal }) =>
fetch("/api/laporan", { signal }).then((res) => res.json()),
})fetch("/api/laporan", { signal }) aborts the request when the signal fires. TanStack Query triggers this on component unmount, when the query is cancelled via queryClient.cancelQueries, or when the queryKey changes. The result: no wasteful requests burning bandwidth.
A dependent query waits for another query's data before running. Use enabled and combine the dependent value into the queryKey:
const { data: pengguna } = useQuery({
queryKey: ["pengguna"],
queryFn: ambilPengguna,
})
const { data: postingan } = useQuery({
queryKey: ["postingan", pengguna?.id],
queryFn: () => ambilPostingan(pengguna.id),
enabled: Boolean(pengguna?.id),
})enabled: Boolean(pengguna?.id) prevents the second query from running before pengguna.id is available. Including pengguna?.id in the queryKey ensures a separate cache per user — switching users means fresh data, not stale queries.
Multiple useQuery calls in one component run in parallel automatically. TanStack Query detects new queries on every render and executes them simultaneously — none of them waits for another, unless you deliberately use the dependent pattern.
By default, refetch on window focus only happens in the active tab. To sync all tabs, plug a BroadcastChannel into the queryClient:
import { BroadcastChannel } from "broadcast-channel"
const channel = new BroadcastChannel("tanstack-cache")
channel.onmessage = (event) => {
if (event.data.type === "refetch") {
queryClient.refetchQueries({ type: "active" })
}
}new BroadcastChannel("tanstack-cache") creates a communication channel between tabs from the same origin. When one tab receives a refetch message, all active tabs call queryClient.refetchQueries({ type: "active" }) so the data always looks identical wherever the user is working.
Warning
BroadcastChannel is available in modern browsers, but not in all older environments. Before using it in production, check your target browsers' support or add a fallback to the storage event.
Episode 8 wrapped up advanced query patterns: prefetching in loaders and on hover for instant navigation, cancellation with AbortSignal to discard wasteful requests, dependent and parallel queries to control ordering and speed, and BroadcastChannel for cross-tab sync.
Key takeaways:
In the next episode, episode 9, we'll discuss table advanced features — column visibility and grouping, aggregation, row selection and expansion, virtualized tables with TanStack Virtual, and custom cell rendering. Back to TanStack Table, but with the features used in enterprise apps!