Solid Query 是 TanStack Query 的官方 SolidJS 适配器,它能让你在 Web 应用中轻松实现数据获取、缓存、同步和更新服务端状态。
SolidJS 作为一个快速、响应式且声明式的用户界面构建库,正日益受到欢迎。它开箱即用地提供了许多功能。诸如 createSignal、createStore 等基础功能非常适合管理客户端状态。与其他 UI 库不同,SolidJS 对异步数据管理有着独到的见解。createResource API 是处理 SolidJS 应用中服务端状态的强大基础功能。resource 是一种特殊的信号 (signal),可在数据加载状态时触发 Suspense 边界。
import { createResource, ErrorBoundary, Suspense } from 'solid-js'
import { render } from 'solid-js/web'
function App() {
const [repository] = createResource(async () => {
const result = await fetch('https://api.github.com/repos/TanStack/query')
if (!result.ok) throw new Error('Failed to fetch data')
return result.json()
})
return (
<div>
<div>Static Content</div>
{/* An error while fetching will be caught by the ErrorBoundary */}
<ErrorBoundary fallback={<div>Something went wrong!</div>}>
{/* Suspense will trigger a loading state while the data is being fetched */}
<Suspense fallback={<div>Loading...</div>}>
<div>{repository()?.updated_at}</div>
</Suspense>
</ErrorBoundary>
</div>
)
}
const root = document.getElementById('root')
render(() => <App />, root!)
import { createResource, ErrorBoundary, Suspense } from 'solid-js'
import { render } from 'solid-js/web'
function App() {
const [repository] = createResource(async () => {
const result = await fetch('https://api.github.com/repos/TanStack/query')
if (!result.ok) throw new Error('Failed to fetch data')
return result.json()
})
return (
<div>
<div>Static Content</div>
{/* An error while fetching will be caught by the ErrorBoundary */}
<ErrorBoundary fallback={<div>Something went wrong!</div>}>
{/* Suspense will trigger a loading state while the data is being fetched */}
<Suspense fallback={<div>Loading...</div>}>
<div>{repository()?.updated_at}</div>
</Suspense>
</ErrorBoundary>
</div>
)
}
const root = document.getElementById('root')
render(() => <App />, root!)
这非常棒!只需几行代码,你就能从 API 获取数据并处理加载和错误状态。但随着应用复杂度的增长,你将需要更多功能来有效管理服务端状态。这是因为服务端状态与客户端状态完全不同。首先,服务端状态:
一旦理解了应用中服务端状态的本质,更多挑战将接踵而至,例如:
此时 Solid Query 应运而生。该库封装了 createResource,并提供了一系列钩子和工具来有效管理服务端状态。它开箱即用、零配置,并可根据应用增长按需定制。
从技术角度来看,Solid Query 能:
在下面的示例中,你可以看到 Solid Query 最基本、简单的用法,用于获取 TanStack Query GitHub 项目的统计信息:
import { ErrorBoundary, Suspense } from 'solid-js'
import {
useQuery,
QueryClient,
QueryClientProvider,
} from '@tanstack/solid-query'
function App() {
const repositoryQuery = useQuery(() => ({
queryKey: ['TanStack Query'],
queryFn: async () => {
const result = await fetch('https://api.github.com/repos/TanStack/query')
if (!result.ok) throw new Error('Failed to fetch data')
return result.json()
},
staleTime: 1000 * 60 * 5, // 5 minutes
throwOnError: true, // Throw an error if the query fails
}))
return (
<div>
<div>Static Content</div>
{/* An error while fetching will be caught by the ErrorBoundary */}
<ErrorBoundary fallback={<div>Something went wrong!</div>}>
{/* Suspense will trigger a loading state while the data is being fetched */}
<Suspense fallback={<div>Loading...</div>}>
{/*
The `data` property on a query is a SolidJS resource
so it will work with Suspense and transitions out of the box!
*/}
<div>{repositoryQuery.data?.updated_at}</div>
</Suspense>
</ErrorBoundary>
</div>
)
}
const root = document.getElementById('root')
const client = new QueryClient()
render(
() => (
<QueryClientProvider client={client}>
<App />
</QueryClientProvider>
),
root!,
)
import { ErrorBoundary, Suspense } from 'solid-js'
import {
useQuery,
QueryClient,
QueryClientProvider,
} from '@tanstack/solid-query'
function App() {
const repositoryQuery = useQuery(() => ({
queryKey: ['TanStack Query'],
queryFn: async () => {
const result = await fetch('https://api.github.com/repos/TanStack/query')
if (!result.ok) throw new Error('Failed to fetch data')
return result.json()
},
staleTime: 1000 * 60 * 5, // 5 minutes
throwOnError: true, // Throw an error if the query fails
}))
return (
<div>
<div>Static Content</div>
{/* An error while fetching will be caught by the ErrorBoundary */}
<ErrorBoundary fallback={<div>Something went wrong!</div>}>
{/* Suspense will trigger a loading state while the data is being fetched */}
<Suspense fallback={<div>Loading...</div>}>
{/*
The `data` property on a query is a SolidJS resource
so it will work with Suspense and transitions out of the box!
*/}
<div>{repositoryQuery.data?.updated_at}</div>
</Suspense>
</ErrorBoundary>
</div>
)
}
const root = document.getElementById('root')
const client = new QueryClient()
render(
() => (
<QueryClientProvider client={client}>
<App />
</QueryClientProvider>
),
root!,
)
确实如此!但正是这几行代码开启了一个全新的可能性世界。在上面的示例中,你的查询会被缓存 5 分钟,这意味着如果应用中任何地方在 5 分钟内挂载了使用相同查询的新组件,它将不会重新获取数据,而是使用缓存数据。这只是 Solid Query 开箱即用提供的众多功能之一。其他功能包括: