Das Paket @tanstack/solid-query bietet eine erstklassige API für die Verwendung von TanStack Query mit SolidJS.
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>
)
}
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>
)
}
Solid Query bietet nützliche Primitive und Funktionen, die die Verwaltung von Serverzuständen in SolidJS-Anwendungen erleichtern.
Solid Query bietet eine API, die React Query ähnelt, es gibt jedoch einige wichtige Unterschiede, die Sie beachten sollten.
// ❌ react version
useQuery({
queryKey: ['todos', todo],
queryFn: fetchTodos,
})
// ✅ solid version
useQuery(() => ({
queryKey: ['todos', todo],
queryFn: fetchTodos,
}))
// ❌ react version
useQuery({
queryKey: ['todos', todo],
queryFn: fetchTodos,
})
// ✅ solid version
useQuery(() => ({
queryKey: ['todos', todo],
queryFn: fetchTodos,
}))
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>
)
}
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>
)
}
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>
)
}
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>
)
}
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>
)
}
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>
)
}
Fehler können mit der nativen ErrorBoundary-Komponente von SolidJS abgefangen und zurückgesetzt werden. Setzen Sie throwOnError oder die Option suspense auf true, um sicherzustellen, dass Fehler an die ErrorBoundary weitergegeben werden.
Da die Eigenschaftsverfolgung über die feingranulare Reaktivität von Solid erfolgt, sind Optionen wie notifyOnChangeProps nicht erforderlich.