TanStack Query V5 - useQuery API 解析
前情提要:
TanStack Query(前身為 React Query) 是我過去一年內最喜歡的 React 生態系工具之一。其中 useQuery 則是我使用最多的 hooks。我最喜愛 useQuery 的地方在於它幾乎涵蓋了所有常見的異步請求工作流程。在大多數應用場景中,使用一個 useQuery 就可以解決過去需要大量手動處理的異步邏輯。然而,它的功能和配置選項繁多,這點也讓我有時感到困擾,總是容易忘記如何正確使用 useQuery @@
因此決定用這篇筆記一次摸熟 useQuery 所有配置選項、回傳值的定義與用法,希望可以減少日後閱讀文件時重新理解的時間。
useQuery 接受兩個參數:一個是配置物件,另一個則是可選的 queryClient。
const {
data,
error,
isLoading,
refetch,
...otherQueryInfo
} = useQuery(options, queryClient);
基本用法
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
type User = {
id: number;
name: string;
email: string;
};
const fetchUser = async (id: number): Promise<User> => {
const response = await axios.get(`/api/users/${id}`);
return response.data;
};
const UserComponent: React.FC<{ userId: number }> = ({ userId }) => {
const { data, isLoading, isError, error, refetch } = useQuery(['user', userId], () => fetchUser(userId));
if (isLoading) {
return <div>Loading...</div>;
}
if (isError) {
return <div>Error: {(error as Error).message}</div>;
}
return (
<div>
<h2>{data?.name}</h2>
<p>Email: {data?.email}</p>
<button onClick={() => refetch()}>Refetch</button>
</div>
);
};
export default UserComponent;
Options 配置物件
基本配置
- queryKey:
unknown[]
(必填)- 查詢的唯一鍵,當這個鍵變更時,會觸發重新查詢。
- 範例:
['user', 1]
- queryFn:
(context: QueryFunctionContext) => Promise<TData>
(必填)- 負責資料請求的函數,必須返回一個 Promise。
- 範例:
async () => { const response = await axios.get('/api/user'); return response.data; }
執行條件與狀態控制
- enabled:
boolean | (query: Query) => boolean
(選填,預設值:true
)- 控制查詢是否應自動執行,適用於依賴其他資料的查詢。
- retry:
boolean | number | (failureCount: number, error: TError) => boolean
(選填,預設值:3
)- 查詢失敗後應重試的次數,或自訂的重試邏輯。
- retryOnMount:
boolean
(選填,預設值:true
)- 當元件重新掛載時,是否重新查詢(在存在錯誤的情況下)。
- retryDelay:
number | (retryAttempt: number, error: TError) => number
(選填)- 設定重試之間的延遲時間,支援如指數型回退等策略。
- refetchOnMount:
boolean | "always" | ((query: Query) => boolean | "always")
(選填,預設值:true
)- 當元件掛載 時是否重新查詢。
- refetchOnWindowFocus:
boolean | "always" | ((query: Query) => boolean | "always")
(選填,預設值:true
)- 當視窗重新獲得焦點時是否重新查詢。
- refetchOnReconnect:
boolean | "always" | ((query: Query) => boolean | "always")
(選填,預設值:true
)- 當網路重新連接時是否重新查詢。
快取與資料處理
- staleTime:
number | (query: Query) => number
(選填,預設值:0
)- 控制資料被認為 "過時" 前的時間(毫秒)。
- gcTime:
number | Infinity
(選填,預設值:5 * 60 * 1000
或Infinity
用於 SSR)- 設定未使用的快取資料應保留在記憶體中的時間。
- initialData:
TData | () => TData
(選填)- 設定查詢的初始資料,如果設定了此值,資料會被視為 "過時"(除非另設
staleTime
)。
- 設定查詢的初始資料,如果設定了此值,資料會被視為 "過時"(除非另設
- initialDataUpdatedAt:
number | (() => number | undefined)
(選填)- 設定初始資料的更新時間戳。
- placeholderData:
TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TData
(選填)- 在查詢進行中的時候顯示的佔位資料,當查詢完成後會被實際資料覆蓋。
- structuralSharing:
boolean | (oldData: unknown | undefined, newData: unknown) => unknown
(選填,預設值:true
)- 用於在舊資料和新資料之間進行結構共享,提升性能。
- select:
(data: TData) => unknown
(選填)- 用來選擇或轉換查詢返回的資料。
網路狀態與背景操作
- networkMode:
'online' | 'always' | 'offlineFirst'
(選填,預設值:'online'
)- 控制查詢應如何在網路狀態變化時運行。
- refetchInterval:
number | false | ((query: Query) => number | false | undefined)
(選填)- 設定自動重新查詢的間隔時間(毫秒),如果為
false
,則停用自動重新查詢。
- 設定自動重新查詢的間隔時間(毫秒),如果為
- refetchIntervalInBackground:
boolean
(選填,預設值:false
)- 控制當視窗/標籤頁在背景中時,是否繼續重新查詢。
錯誤處理與其他
- throwOnError:
undefined | boolean | (error: TError, query: Query) => boolean
(選填,預設值:undefined
)- 設定查詢發生錯誤時是否拋出錯誤,或是將錯誤返回作為狀態處理。
- queryKeyHashFn:
(queryKey: QueryKey) => string
(選填)- 自訂
queryKey
的雜湊函數。
- 自訂
- notifyOnChangeProps:
string[] | "all" | (() => string[] | "all" | undefined)
(選填)- 控制在哪些屬性變更時元件會重新渲染。
- meta:
Record<string, unknown>
(選填)- 儲存查詢的額外中繼資料,這些資料可以在查詢過程中被使用。
- queryClient:
QueryClient
(選填)- 如果需要,可以傳入自訂的
QueryClient
。
- 如果需要,可以傳入自訂的
回傳值
資料類
- data:
TData
- 查詢成功後的資料,如果查詢未成功,默認為
undefined
。
- 查詢成功後的資料,如果查詢未成功,默認為
- dataUpdatedAt:
number
- 資料最近一次成功更新的時間戳。
- isStale:
boolean
- 如果資料是過時的,則為
true
。
- 如果資料是過時的,則為
- isPlaceholderData:
boolean
- 如果當前顯示的是佔位資料,則為
true
。
- 如果當前顯示的是佔位資料,則為
狀態類
- status:
'pending' | 'error' | 'success'
- 查詢的當前狀態:
pending
: 尚未完成查詢。error
: 查詢失敗。success
: 查詢成功。
- 查詢的當前狀態:
- fetchStatus:
'fetching' | 'paused' | 'idle'
- 描述查詢的進行狀態:
fetching
: 查詢正在執行中。paused
: 查詢暫停。idle
: 查詢處於空閒狀態。
- 描述查詢的進行狀態:
- isFetched:
boolean
- 查詢是否曾被取用過。
- isFetchedAfterMount:
boolean
- 元件掛載後是否曾取用過查詢資料。
status
的衍生狀態
- isPending:
boolean
- 當
status
為pending
時為true
。
- 當
- isSuccess:
boolean
- 當
status
為success
時為true
。
- 當
- isError:
boolean
- 當
status
為error
時為true
。
- 當