Solid Query 是 TanStack Query 的官方 SolidJS 轉接器,能讓你在網頁應用程式中輕鬆實現 資料獲取、快取、同步與更新伺服器狀態 (server state)。
SolidJS 作為一個快速、反應式且宣告式的使用者介面建構函式庫,近年來越來越受歡迎。它內建了許多開箱即用的功能,像是 createSignal 和 createStore 等基本功能非常適合管理客戶端狀態 (client state)。與其他 UI 函式庫不同,SolidJS 對於非同步資料管理有明確的設計理念。createResource API 就是一個在 SolidJS 應用中處理伺服器狀態 (server state) 的絕佳基本功能。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 獲取資料並處理載入和錯誤狀態。但是,隨著應用程式複雜度增加,你會需要更多功能來有效管理伺服器狀態 (server state)。這是因為 伺服器狀態與客戶端狀態完全不同。首先,伺服器狀態:
一旦你理解了應用中伺服器狀態的本質,更多挑戰將接踵而至,例如:
這就是 Solid Query 的用武之地。這個函式庫封裝了 createResource,並提供一組鉤子 (hooks) 和工具來有效管理伺服器狀態。它開箱即用,零配置即可運作良好,並能隨著應用成長自訂。
從技術角度來看,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 開箱即用的眾多功能之一。其他功能包括: