原文鏈接:https://zhuanlan.zhihu.com/p/89570321 作者:飛冰-chenbin92
說明:本文內容主要來源於 SWR 的 官方文檔 以及 GitHub zeit/swr 倉庫,本篇主要爲功能簡介篇。
簡介
React Hooks library for remote data fetching
一個用於請求遠程數據的 React Hooks 庫,官網的快速開始示例如下:
import useSWR from 'swr'
function Profile () {
const { data, error } = useSWR('/api/user', fetch)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
上述示例是一個最基礎的前端基礎請求例子, useSWR
接受一個 key
和一個異步請求函數 fetch
作爲參數。 key
是數據的唯一標識符,通常是 API URL,並且 fetch
接受 key
作爲其參數,完成具體的數據請求行爲並異步返回數據。
useSWR
返回 2 個值: data
和 error
, 分別對應請求返回的數據結果和錯誤,當 data
爲空時,可以指定渲染對應的 UI;當請求(獲取)尚未完成時,數據將是 undefined
的;當得到響應時它會根據獲取的結果設置 data
和 error
然後重新渲染組件。其中第二個參數 fetch
部分可以是任何異步函數,因此可以使用你喜歡的任何數據獲取庫來處理這這部分。
功能
SWR 相比常見的數據請求庫提供了很多很酷且很有腦洞的特性,比如導航切換時使用緩存數據進行優先渲染然後在進行對比更新,數據在 focus
時更新,輪詢檢查更新,分頁按需更新等等。
- Transport and protocol agnostic data fetching
- Fast page navigation
- Revalidation on focus
- Interval polling
- Local mutation
- Pagination
- TypeScript ready
- Suspense mode
- Minimal API
Focus Revalidation
當重新聚焦頁面或在不同的標籤頁之間切換時,SWR 會自動重新獲取數據,這對於立即同步到最新狀態很有用。常見的場景如電腦進入睡眠狀態的情況下,重新刷新數據是很有幫助的。
如下演示:使用焦點自動在頁面之間同步登錄狀態。
Fast Navigation
當瀏覽頁面或系統中的某個部分時,也或者當點擊返回按鈕時,SWR 將會加載緩存的數據,同時爲了達到最終數據的一致性,一旦從緩存加載數據,SWR 會自動重新獲取原始的數據。
如下演示:SWR 通過使用緩存數據使得頁面顯示得更快,然後用最新的數據更新緩存。
Refetch on Interval
在許多情況下,由於多個設備、多個用戶、多個選項卡,數據會發生更改。隨着時間的推移,我們如何更新屏幕上的數據?SWR 也提供了自動重新提取數據的選項,且只有與 hook 相關的組件在屏幕上時纔會進行重新更新。
如下演示:當進行更改是,兩個會話最終呈現相同的數據。
Local mutation
在許多情況下,對數據應用局部突變是一種讓更改感覺更快的好方法—無需等待遠程數據源。局部突變是一種完全可選的方法,用於設置臨時的局部狀態,該狀態將在下次重新驗證時自動更新。
SWR 提供了一個 mutate
方法來直接修改請求返回的數據,此時請求中的 key 就派上用場了。官方給的例子是用於樂觀更新,提交表單時提前修改前端展現的數據,然後發請求進行 revalidate 更新。
Scroll Position Recovery and Pagination
SWR 內置支持數據以 塊(chunks) 的形式返回數據的 APIs ,以及用於"加載更多"的相應 UI。此外,當導航回到“加載更多”的列表時,包括滾動位置在內的所有內容都將自動恢復。
如下:ZEIT 儀表板上的無限滾動用戶界面,SWR 將恢復你的滾動位置。
Custom Data Fetching
SWR 默認用原生的 fetch
做請求,並假設使用 REST 風格的 API 進行調用,但是你也可以指定其他的任何異步請求庫作爲第二個參數,比如下面的例子是 graphql 示例:
import { request } from 'graphql-request'
import useSWR from 'swr'
const API = 'https://api.graph.cool/simple/v1/movies'
function Profile () {
const { data, error } = useSWR(
`{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}`,
query => request(API, query)
)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>Movie: {data.title}!</div>
}
Dependent Fetching
SWR 允許獲取依賴於其他數據的數據,它可以確保最大程度的並行性(avoiding waterfalls)。
import useSWR from 'swr'
function MyProjects () {
const { data: user } = useSWR('/api/user')
const { data: projects } = useSWR(
() => '/api/projects?uid=' + user.id
)
// When passing a function, SWR will use the
// return value as `key`. If the function throws,
// SWR will know that some dependencies are not
// ready. In this case it is `user`.
if (!projects) return 'loading...'
return 'You have ' + projects.length + ' projects'
}
Suspense
還可以將 SWR Hooks 與 React Suspense 一起使用,只需 SWR 的配置中啓用 suspense: true
,一切都會順利進行。
import { Suspense } from 'react'
import useSWR from 'swr'
function Profile () {
const { data } = useSWR(
'/api/user',
fetch,
{ suspense: true }
)
return <div>hello, {data.name}</div>
}
function App () {
return (
<Suspense fallback={<div>loading...</div>}>
<Profile/>
</Suspense>
)
}
總結
目前來看 SWR 主要是基於 stale-while-revalidate
概念,實現的一個 React Hooks 版本的數據請求庫,可以從上面分析的功能發現其核心是專注在 異步數據請求 這個最基本的訴求上,同時帶入了很多新的腦洞以及很多新思路,相比現有的請求庫未來可能有更多的可能性,是具有較大潛力的請求類工具庫。