# useSWR ## 基本用法 ```typescript= const key = `api/news` const fetcher = (url: string) => axios(url).then((res) => res.data); const { data, error } = useSWR(key, fetcher) ``` 第一個參數`key`是一個字串,有兩個功能: 1. 作為**唯一**的識別符,通常是 API URL,一個頁面中如有多組相同的`key`,會自動被 cache,避免重複打 API。 2. 傳遞給`fetcher`取得資料。 第二個參數`fetcher`是一個函數,用來包裝取得資料的方法,接收 `key` 值作為 `url` 使用。 > 可以使用原生`fetch`,或是`Axios`、`GraphQL`之類的函數庫 [官方範例](https://swr.vercel.app/docs/data-fetching)。 ## 在 getServerSideProps 頁面使用 ### 範例 有一個 server side render 頁面需要做 pagination 分頁,要可以設定撈取資料筆數及抓到當前頁數,使用 useSWR 打 API 後傳到元件中。 首先在`api/`資料夾路徑下創建一支`data.api.ts`的檔案。 ```typescript= // data.api.ts import useSWR from 'swr'; import qs from 'qs'; const fetcher = (url: string) => axios(url).then((res) => res.data); export const useFetchData = (dataRequest: DataRequest) => { const page: number = dataRequest.page; const rows: number = dataRequest.rows; const request: { [key: string]: any; } = { page, rows, }; const query = qs.stringify(request); const key = `/event/list?${query}`; const { data, error } = useSWR<DataResponse>(key, fetcher); return { eventData: data, error }; }; ``` 每次寫 API 時,都要在`__types__/`資料夾內創建`data.d.ts`的檔案,為這支 API 所產生的資料定義 type。這個範例中先為 request 與 response 定義 type,將它們分別命名為`DataRequest`及`DataResponse`,response 回傳的資料會是物件陣列,要再額外寫一個 `DataItem` 的 type 定義它。 ```typescript= type DataRequest = { rows: number; page: number; } type DataResponse = { total: number; rows: DataItem[]; } type DataItem = { title: string; descript: string; } ``` 都寫好後,在`page/`頁面中直接使用即可,在`getServerSideProps`設定每頁抓取幾筆資料`rows`,用`query`抓取(網址)的 ?page=,傳到 Page 中打 API 撈取資料。 ```typescript= // page.tsx import { useFetchData } from 'api/data.ts' interface HomeProps { rows: number; page: number; } const Page = ({ rows, page }: HomeProps) => { const { eventData, error } = useFetchData({ rows, page }); // ... } export const getServerSideProps: GetServerSideProps = async ({ query }) => { const rows: number = 4; const page: number = query.page !== undefined ? parseInt(query.page as string) : 1; return { props: { page, rows } }; }; // ... ``` ###### tags: `React`