Shikhil Saxena

Aug 13, 2025 • 2 min read

🧠 MicroStrategy’s Bold Bet on Bitcoin and AI

As I've described in #18: Inside React Query, React Query consists of one global state - the QueryCache - that holds information about all Queries. Whenever something in a Query changes, we want to inform all QueryObservers (the things that get created with useQuery) about that change.

Now ideally, we'd want to avoid that every component is subscribed to everything. A change in the todos Query shouldn't re-render a component that is only interested in the profile Query. Otherwise, we could've just used a top-level useState and distribute that with React Context throughout our application. Controlling subscriptions, and making them fine-grained, is why state management solutions exist in the first place.

As you may know, React Query has the above mentioned feature built-in. Of course, useQuery doesn't subscribe to the whole QueryCache. The QueryKey you pass to useQuery gets hashed deterministically into a QueryHash, and useQuery will only get notified about changes to that Query.

In essence, it's like we're pre-filtering down to the Query you're interested in. And mostly, that's enough. Data from one endpoint changes, your component re-renders. Data from another endpoint changes, it doesn't. So what more do we need?

select is an option we can pass to useQuery to pick, transform, or otherwise compute a result that our component should subscribe to. It's a way to get derived state that is very similar to how deriving data with selectors works in redux.

You might not have noticed it in the examples above, but they are all valid TypeScript code. In fact, they are not only valid, but also type-safe and inferred. That means the data field on the object you get back from useQuery will be typed to whatever select returns.

However, this only works if you let type inference do it's magic 🪄, which means we don't want to manually "provide" generic type parameters to useQuery. Please read #6: React Query and TypeScript for more information on that if you haven't done so already.

This is relatively easy to adhere to, but brings one question: How can I write a reusable abstraction in TypeScript that includes select? What type sorcery is needed to e.g. make productOptions that get select as an argument?

Join Shikhil on Peerlist!

Join amazing folks like Shikhil and thousands of other builders on Peerlist.

peerlist.io/

It’s available... this username is available! 😃

Claim your username before it's too late!

This username is already taken, you’re a little late.😐

0

8

0