Skip to main content

useQuery()

Data rendering without the fetch.

Access any Queryable Schema's store value; like Entity, All, Collection, Query, and Union. If the value does not exist, returns undefined.

useQuery() is reactive to data mutations; rerendering only when necessary. Returns undefined when data is Invalid.

tip

Queries are a great companion to efficiently render aggregate computations like those that use groupBy, map, reduce, and filter.

Usage

import { schema } from '@data-client/rest'; import { useQuery } from '@data-client/react'; import { PostResource } from './PostResource';  const queryTotalVotes = new schema.Query(  PostResource.getList.schema,  posts => posts.reduce((total, post) => total + post.votes, 0), );  export default function TotalVotes({ userId }: Props) {  const totalVotes = useQuery(queryTotalVotes, { userId });  return (  <center>  <small>{totalVotes} votes total</small>  </center>  ); } interface Props {  userId: number; } 
🔴 Live Preview
Store

See truthiness narrowing for more information about type handling

Types

function useQuery(
schema: Queryable,
...args: SchemaArgs<typeof schema>
): DenormalizeNullable<typeof endpoint.schema> | undefined;

Queryable

Queryable schemas require an queryKey() method that returns something. These include Entity, All, Collection, Query, and Union.

interface Queryable {
queryKey(
args: readonly any[],
queryKey: (...args: any) => any,
getEntity: GetEntity,
getIndex: GetIndex,
// Must be non-void
): {};
}

Examples

Sorting & Filtering

Query provides programmatic access to the Reactive Data Client store.

import { schema } from '@data-client/rest'; import { useQuery, useFetch } from '@data-client/react'; import { UserResource, User } from './UserResource';  interface Args {  asc: boolean;  isAdmin?: boolean; } const sortedUsers = new schema.Query(  new schema.All(User),  (entries, { asc, isAdmin }: Args = { asc: false }) => {  let sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));  if (isAdmin !== undefined)  sorted = sorted.filter(user => user.isAdmin === isAdmin);  if (asc) return sorted;  return sorted.reverse();  }, );  function UsersPage() {  useFetch(UserResource.getList);  const users = useQuery(sortedUsers, { asc: true });  if (!users) return <div>No users in cache yet</div>;  return (  <div>  {users.map(user => (  <div key={user.pk()}>{user.name}</div>  ))}  </div>  ); } render(<UsersPage />); 
🔴 Live Preview
Store

Remaining Todo total

Queries can also be used to compute aggregates

More Demos

Data fallbacks

In this case Ticker is constantly updated from a websocket stream. However, there is no bulk/list fetch for Ticker - making it inefficient for getting the prices on a list view.

So in this case we can fetch a list of Stats as a fallback since it has price data as well.

More Demos