snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
217
docs/framework/solid/quick-start.md
Normal file
217
docs/framework/solid/quick-start.md
Normal file
@@ -0,0 +1,217 @@
|
||||
---
|
||||
id: quick-start
|
||||
title: Quick Start
|
||||
---
|
||||
|
||||
The `@tanstack/solid-query` package provides a 1st-class API for using TanStack Query with SolidJS.
|
||||
|
||||
## Example
|
||||
|
||||
```tsx
|
||||
import {
|
||||
QueryClient,
|
||||
QueryClientProvider,
|
||||
useQuery,
|
||||
} from '@tanstack/solid-query'
|
||||
import { Switch, Match, For } from 'solid-js'
|
||||
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
function Example() {
|
||||
const query = useQuery(() => ({
|
||||
queryKey: ['todos'],
|
||||
queryFn: fetchTodos,
|
||||
}))
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Switch>
|
||||
<Match when={query.isPending}>
|
||||
<p>Loading...</p>
|
||||
</Match>
|
||||
<Match when={query.isError}>
|
||||
<p>Error: {query.error.message}</p>
|
||||
</Match>
|
||||
<Match when={query.isSuccess}>
|
||||
<For each={query.data}>{(todo) => <p>{todo.title}</p>}</For>
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Example />
|
||||
</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.
|
||||
|
||||
- Arguments to `solid-query` primitives (like `useQuery`, `useMutation`, `useIsFetching`) are functions, so that they can be tracked in a reactive scope.
|
||||
|
||||
```tsx
|
||||
// ❌ react version
|
||||
useQuery({
|
||||
queryKey: ['todos', todo],
|
||||
queryFn: fetchTodos,
|
||||
})
|
||||
|
||||
// ✅ solid version
|
||||
useQuery(() => ({
|
||||
queryKey: ['todos', todo],
|
||||
queryFn: fetchTodos,
|
||||
}))
|
||||
```
|
||||
|
||||
- Suspense works for queries out of the box if you access the query data inside a `<Suspense>` boundary.
|
||||
|
||||
```tsx
|
||||
import { For, Suspense } from 'solid-js'
|
||||
|
||||
function Example() {
|
||||
const query = useQuery(() => ({
|
||||
queryKey: ['todos'],
|
||||
queryFn: fetchTodos,
|
||||
}))
|
||||
return (
|
||||
<div>
|
||||
{/* ✅ Will trigger loading fallback, data accessed in a suspense boundary. */}
|
||||
<Suspense fallback={'Loading...'}>
|
||||
<For each={query.data}>{(todo) => <div>{todo.title}</div>}</For>
|
||||
</Suspense>
|
||||
{/* ❌ Will not trigger loading fallback, data not accessed in a suspense boundary. */}
|
||||
<For each={query.data}>{(todo) => <div>{todo.title}</div>}</For>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
- Solid Query primitives 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,
|
||||
useQuery,
|
||||
} from '@tanstack/solid-query'
|
||||
import { Match, Switch } from 'solid-js'
|
||||
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Example />
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
function Example() {
|
||||
// ❌ react version -- supports destructing outside reactive context
|
||||
// const { isPending, error, data } = useQuery({
|
||||
// queryKey: ['repoData'],
|
||||
// queryFn: () =>
|
||||
// fetch('https://api.github.com/repos/tannerlinsley/react-query').then(
|
||||
// (res) => res.json()
|
||||
// ),
|
||||
// })
|
||||
|
||||
// ✅ solid version -- does not support destructuring outside reactive context
|
||||
const query = useQuery(() => ({
|
||||
queryKey: ['repoData'],
|
||||
queryFn: () =>
|
||||
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(
|
||||
(res) => res.json(),
|
||||
),
|
||||
}))
|
||||
|
||||
// ✅ access query properties in JSX reactive context
|
||||
return (
|
||||
<Switch>
|
||||
<Match when={query.isPending}>Loading...</Match>
|
||||
<Match when={query.isError}>Error: {query.error.message}</Match>
|
||||
<Match when={query.isSuccess}>
|
||||
<div>
|
||||
<h1>{query.data.name}</h1>
|
||||
<p>{query.data.description}</p>
|
||||
<strong>👀 {query.data.subscribers_count}</strong>{' '}
|
||||
<strong>✨ {query.data.stargazers_count}</strong>{' '}
|
||||
<strong>🍴 {query.data.forks_count}</strong>
|
||||
</div>
|
||||
</Match>
|
||||
</Switch>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
- Signals and store values can be passed in directly to function arguments. Solid Query will update the query `store` automatically.
|
||||
|
||||
```tsx
|
||||
import {
|
||||
QueryClient,
|
||||
QueryClientProvider,
|
||||
useQuery,
|
||||
} from '@tanstack/solid-query'
|
||||
import { createSignal, For } from 'solid-js'
|
||||
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
function Example() {
|
||||
const [enabled, setEnabled] = createSignal(false)
|
||||
const [todo, setTodo] = createSignal(0)
|
||||
|
||||
// ✅ passing a signal directly is safe and observers update
|
||||
// automatically when the value of a signal changes
|
||||
const todosQuery = useQuery(() => ({
|
||||
queryKey: ['todos'],
|
||||
queryFn: fetchTodos,
|
||||
enabled: enabled(),
|
||||
}))
|
||||
|
||||
const todoDetailsQuery = useQuery(() => ({
|
||||
queryKey: ['todo', todo()],
|
||||
queryFn: fetchTodo,
|
||||
enabled: todo() > 0,
|
||||
}))
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Switch>
|
||||
<Match when={todosQuery.isPending}>
|
||||
<p>Loading...</p>
|
||||
</Match>
|
||||
<Match when={todosQuery.isError}>
|
||||
<p>Error: {todosQuery.error.message}</p>
|
||||
</Match>
|
||||
<Match when={todosQuery.isSuccess}>
|
||||
<For each={todosQuery.data}>
|
||||
{(todo) => (
|
||||
<button onClick={() => setTodo(todo.id)}>{todo.title}</button>
|
||||
)}
|
||||
</For>
|
||||
</Match>
|
||||
</Switch>
|
||||
<button onClick={() => setEnabled(!enabled())}>Toggle enabled</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Example />
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
- Errors can be caught and reset using SolidJS' native `ErrorBoundary` component.
|
||||
Set `throwOnError` or the `suspense` option to `true` to make sure errors are thrown to the `ErrorBoundary`
|
||||
|
||||
- Since Property tracking is handled through Solid's fine grained reactivity, options like `notifyOnChangeProps` are not needed
|
||||
Reference in New Issue
Block a user