--- id: overview title: Solid Query --- The `@tanstack/solid-query` package provides a 1st-class API for using TanStack Query with SolidJS. ## Example ```tsx import { QueryClient, QueryClientProvider, createQuery } from '@tanstack/solid-query' import { Switch, Match, For } from 'solid-js' const queryClient = new QueryClient() function Example() { const query = createQuery(() => ['todos'], fetchTodos) return (

Loading...

Error: {query.error.message}

{(todo) =>

{todo.title}

}
) } function App() { return ( ) } ``` ## Available Functions Solid Query offers useful primitives and functions that will make managing server state in SolidJS apps easier. - `createQuery` - `createQueries` - `createInfiniteQueries` - `createMutation` - `useIsFetching` - `useIsMutating` - `useQueryClient` - `QueryClient` - `QueryClientProvider` ## Important Differences between Solid Query & React Query Solid Query offers an API similar to React Query, but there are some key differences to be mindful of. - To maintain their reactivity, Query keys need to be wrapped inside a function while using `createQuery`, `createQueries`, `createInfiniteQuery` and `useIsFetching`. ```tsx // ❌ react version useQuery(["todos", todo], fetchTodos) // ✅ solid version createQuery(() => ["todos", todo()], fetchTodos) ``` - Suspense works for queries out of the box if you access the query data inside a `` boundary. ```tsx import { For, Suspense } from 'solid-js' function Example() { const query = createQuery(() => ['todos'], fetchTodos) return (
{/* ✅ Will trigger loading fallback, data accessed in a suspense context. */} {(todo) =>
{todo.title}
}
{/* ❌ Will not trigger loading fallback, data not accessed in a suspense context. */} {(todo) =>
{todo.title}
}
) } ``` - Solid Query primitives (`createX`) do not support destructuring. The return value from these functions is a store, and their properties are only tracked in a reactive context. ```tsx import { QueryClient, QueryClientProvider, createQuery } from '@tanstack/solid-query' import { Match, Switch } from 'solid-js' const queryClient = new QueryClient() export default function App() { return ( ) } function Example() { // ❌ react version -- supports destructing outside reactive context // const { isLoading, error, data } = useQuery(['repoData'], () => // fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res => // res.json() // ) // ) // ✅ solid version -- does not support destructuring outside reactive context const query = createQuery( () => ['repoData'], () => fetch('https://api.github.com/repos/tannerlinsley/react-query').then( (res) => res.json(), ), ) // ✅ access query properties in JSX reactive context return ( Loading... Error: {query.error.message}

{query.data.name}

{query.data.description}

👀 {query.data.subscribers_count}{' '} ✨ {query.data.stargazers_count}{' '} 🍴 {query.data.forks_count}
) } ``` - If you want options to be reactive you need to pass them using object getter syntax. This may look strange at first but it leads to more idiomatic solid code. ```tsx import { QueryClient, QueryClientProvider, createQuery, } from '@tanstack/solid-query' import { createSignal, For } from 'solid-js' const queryClient = new QueryClient() function Example() { const [enabled, setEnabled] = createSignal(false) const query = createQuery(() => ['todos'], fetchTodos, { // ❌ passing a signal directly is not reactive // enabled: enabled(), // ✅ passing a function that returns a signal is reactive get enabled() { return enabled() }, }) return (

Loading...

Error: {query.error.message}

{(todo) =>

{todo.title}

}
) } function App() { return ( ) } ``` - Errors can be caught and reset using SolidJS' native `ErrorBoundary` component. `QueryErrorResetBoundary` is not needed with Solid Query - Since Property tracking is handled through Solid's fine grained reactivity, options like `notifyOnChangeProps` are not needed