跳至主要内容

2 篇文章 含有標籤「React Query」

檢視所有標籤

TanStack Query 入門教學筆記 | 學習筆記

· 閱讀時間約 4 分鐘
kdchang

前言

在現代前端開發中,資料取得(Data Fetching)與狀態管理是非常重要的課題。傳統上,我們可能會使用 useEffect 搭配 fetchaxios 來手動管理資料請求,並維護載入狀態、錯誤狀態與資料快取等,但這樣往往容易導致重複程式碼、管理複雜以及效能不佳。

TanStack Query(舊名 React Query)是一個專門用來管理伺服器狀態(server state)的函式庫,極大地簡化了資料抓取、快取、同步、重新整理與錯誤處理的流程。它不只支援 React,也能搭配 Vue、Svelte 等其他框架。

這篇筆記將介紹 TanStack Query 的核心概念與使用方式,並提供一個簡單範例,幫助你快速上手。


重點摘要

  • TanStack Query 是什麼? 一個用於管理非同步伺服器資料的 React Hooks 函式庫,能自動處理快取、背景重新整理、錯誤重試等。

  • 主要功能

    • 自動快取資料,減少重複請求。
    • 自動背景刷新(Background Refetching)保持資料最新。
    • 支援資料同步與離線快取。
    • 強大的錯誤重試與錯誤處理機制。
    • 方便整合 Pagination、Infinite Query。
    • 非常輕量且易於擴充。
  • 核心概念

    • Query:對伺服器資料的請求。
    • Query Key:唯一標識一個 Query 的鍵,決定快取與重新抓取。
    • useQuery Hook:用於發起資料請求並取得資料狀態。
    • Query Client:全域管理 Query 狀態與快取。
  • 安裝方式

    npm install @tanstack/react-query
    # 或者
    yarn add @tanstack/react-query
  • 基本使用步驟

    1. 在 React 根組件包裹 <QueryClientProvider>
    2. 使用 useQuery Hook 進行資料請求。
    3. 使用 dataerrorisLoading 等狀態呈現畫面。
  • 常用參數

    • queryKey:快取與識別用的陣列或字串。
    • queryFn:負責非同步取得資料的函式。
    • enabled:是否啟用該 query。
    • staleTime:資料被視為新鮮的時間(避免頻繁重新抓取)。
    • cacheTime:資料快取存在時間。
    • retry:失敗時重試次數。

實際範例

以下以 React 搭配 TanStack Query 實現一個簡單的使用者列表資料抓取為例:

1. 設定 Query Client

在應用程式最外層(通常是 App.jsindex.js)包裹 QueryClientProvider

import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import UserList from './UserList';

const queryClient = new QueryClient();

function App() {
return (
<QueryClientProvider client={queryClient}>
<UserList />
</QueryClientProvider>
);
}

export default App;

2. 建立 UserList 元件,使用 useQuery 抓取資料

import React from 'react';
import { useQuery } from '@tanstack/react-query';

async function fetchUsers() {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
if (!res.ok) {
throw new Error('網路錯誤');
}
return res.json();
}

function UserList() {
const { data, error, isLoading, isError } = useQuery(['users'], fetchUsers, {
staleTime: 1000 * 60 * 5, // 5分鐘內資料視為新鮮
retry: 2, // 失敗重試2次
});

if (isLoading) return <div>資料載入中...</div>;

if (isError) return <div>錯誤發生:{error.message}</div>;

return (
<ul>
{data.map((user) => (
<li key={user.id}>
{user.name}{user.email}
</li>
))}
</ul>
);
}

export default UserList;

3. 說明

  • useQuery 第一個參數為 query key,這裡用 ['users'] 表示抓取使用者列表。

  • 第二個參數是非同步函式 fetchUsers,負責呼叫 API 並回傳資料。

  • 返回的物件中包含多種狀態:

    • isLoading:資料還在請求中。
    • isErrorerror:請求失敗時的錯誤狀態與訊息。
    • data:請求成功後的資料。
  • staleTime 設定資料多久內視為新鮮,避免頻繁重新抓取。

  • retry 設定失敗時自動重試的次數。


進階應用

  • 背景重新抓取 使用者回到頁面或重新聚焦視窗時,TanStack Query 預設會重新抓取最新資料,保持資料同步。 可透過 refetchOnWindowFocus 控制是否啟用。

  • 資料快取與共享 不同組件如果使用相同 queryKey,會共用快取資料,避免重複請求。

  • Mutation 除了讀取資料,TanStack Query 也提供 useMutation 用於資料修改(新增、更新、刪除)並自動管理快取更新。

  • 分頁與無限滾動 支援分頁資料抓取的 useInfiniteQuery,適合實作滾動載入。


總結

TanStack Query 是一個強大且方便的資料狀態管理工具,解決了傳統手動管理非同步請求的種種痛點。它自動快取、背景重新整理、錯誤重試等機制,大幅提升開發效率與使用者體驗。

React Query 入門教學筆記 | 學習筆記

· 閱讀時間約 4 分鐘
kdchang

前言

隨著前端應用程式越來越複雜,資料的取得、快取、同步更新以及狀態管理成為重要挑戰。傳統使用 useEffect 搭配 fetchaxios 取得資料,會讓程式碼變得冗長且難以維護,特別是需要處理快取、錯誤重試、背景重新整理(refetch)等功能時。

React Query 是一個強大的資料同步庫,它抽象並管理伺服器狀態(server state),讓你能輕鬆完成資料抓取、快取、更新與錯誤處理。透過簡潔的 API 和自動化行為,讓前端開發者能專注於業務邏輯,而非繁瑣的資料管理。

本篇教學將介紹 React Query 的核心概念,並提供簡單的實作範例,讓你快速理解如何在 React 專案中有效率且方便地使用 React Query。


重點摘要

  • React Query 是什麼? 專注於伺服器狀態管理的資料同步庫,提供資料取得、快取、自動重試、背景更新、分頁等功能。

  • 伺服器狀態(Server State) vs 本地狀態(Local State) React Query 管理的是伺服器端資料,不同於用 React 的 useState 管理元件內部的本地狀態。

  • 核心 Hook:useQuery 用來抓取和快取資料,接收一個 key 和一個 fetcher 函式,會自動處理 loading、error、資料快取。

  • 資料快取與自動同步 React Query 會自動快取請求結果,並依設定自動重新抓取,保持資料最新。

  • 背景重新整理(Refetching) 可設定在視窗獲得焦點時自動刷新資料,確保資料同步。

  • 錯誤重試機制 請求失敗時可自動重試,避免因網路波動導致資料錯誤。

  • useMutation 用於資料變更(新增、修改、刪除)操作,並支援變更後自動重新整理相關快取。

  • 全域 Query Client 使用 QueryClient 管理所有查詢狀態,需用 QueryClientProvider 包裹應用程式。

  • 方便整合各種請求函式庫 可搭配 fetchaxios 等任意資料請求方式。


實際範例

1. 安裝

npm install @tanstack/react-query

yarn add @tanstack/react-query

2. 基本設定

在 React 應用的根元件設定 QueryClientQueryClientProvider

import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function App() {
return (
<QueryClientProvider client={queryClient}>
<YourComponent />
</QueryClientProvider>
);
}

export default App;

3. 使用 useQuery 抓取資料

import React from 'react';
import { useQuery } from '@tanstack/react-query';

// 一個模擬的 fetch 函式,從 API 取得使用者清單
async function fetchUsers() {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
if (!res.ok) throw new Error('Network response was not ok');
return res.json();
}

function UserList() {
// 使用 useQuery,第一參數為 key,第二參數為 fetch 函式
const { data, error, isLoading, isError } = useQuery(['users'], fetchUsers);

if (isLoading) return <div>載入中...</div>;

if (isError) return <div>錯誤:{error.message}</div>;

return (
<ul>
{data.map((user) => (
<li key={user.id}>
{user.name} ({user.email})
</li>
))}
</ul>
);
}

export default UserList;

4. 使用 useMutation 進行資料更新

假設有一個新增使用者的 API,使用 useMutation 處理:

import React, { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';

async function addUser(newUser) {
const res = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
body: JSON.stringify(newUser),
headers: { 'Content-Type': 'application/json' },
});
if (!res.ok) throw new Error('新增失敗');
return res.json();
}

function AddUserForm() {
const [name, setName] = useState('');
const queryClient = useQueryClient();

const mutation = useMutation(addUser, {
onSuccess: () => {
// 新增成功後,重新整理 users 快取
queryClient.invalidateQueries(['users']);
},
});

const handleSubmit = (e) => {
e.preventDefault();
mutation.mutate({ name });
};

return (
<form onSubmit={handleSubmit}>
<input value={name} onChange={(e) => setName(e.target.value)} placeholder="使用者名稱" />
<button type="submit">新增使用者</button>
{mutation.isLoading && <p>新增中...</p>}
{mutation.isError && <p>錯誤:{mutation.error.message}</p>}
{mutation.isSuccess && <p>新增成功!</p>}
</form>
);
}

export default AddUserForm;

小結

React Query 提供一套完整且簡潔的 API 來管理伺服器狀態,包含資料取得、快取、錯誤處理與背景更新。透過 useQueryuseMutation,你能輕鬆地處理資料的讀取與更新,讓 React 應用程式更穩定且易維護。

建議在開發中逐步導入 React Query,取代傳統的 useEffect + fetch 模式,尤其是對於複雜的資料流與同步需求,能大幅提升開發效率與使用者體驗。

參考文件

  1. React Query 文件