了解 SWR
狀態機
useSWR
根據 fetcher
函數的狀態,返回 data
、error
、isLoading
和 isValidating
。以下圖表描述了 SWR 在某些情境下如何返回值。
提取與重新驗證
此模式用於提取資料並稍後重新驗證。
鍵值變更
此模式用於提取資料,變更鍵值,然後稍後重新驗證。
鍵值變更 + 先前資料
此模式用於提取資料,變更鍵值,然後使用 keepPreviousData
選項稍後重新驗證。
回退
此模式用於提取資料,並使用回退資料稍後重新驗證。
鍵值變更 + 回退
此模式用於提取資料,變更鍵值,並使用回退資料稍後重新驗證。
鍵值變更 + 先前資料 + 回退
此模式用於提取資料,變更鍵值,並使用 keepPreviousData
選項和回退資料稍後重新驗證。
結合 isLoading 和 isValidating 以獲得更好的使用者體驗
與現有的 isValidating
值相比,isLoading
是一個新的屬性,可以幫助您處理更多一般性的載入情況,以提升使用者體驗。
- 每當有正在進行的要求時(**無論資料是否已載入**),
isValidating
都會變成true
。 - 當有正在進行的要求且**資料尚未載入**時,
isLoading
就會變成true
。
簡單來說,您可以每次在進行重新驗證時使用 isValidating
來指示,並使用 isLoading
來指示 SWR 正在重新驗證但尚未有資料可顯示。
回退資料和先前資料不被視為「已載入的資料」,因此當您使用回退資料或啟用 keepPreviousData 選項時,您可能會有資料可供顯示。
function Stock() {
const { data, isLoading, isValidating } = useSWR(STOCK_API, fetcher, {
refreshInterval: 3000
});
// If it's still loading the initial data, there is nothing to display.
// We return a skeleton here.
if (isLoading) return <div className="skeleton" />;
// Otherwise, display the data and a spinner that indicates a background
// revalidation.
return (
<>
<div>${data}</div>
{isValidating ? <div className="spinner" /> : null}
</>
);
}
您可以在此處 (在新分頁中開啟)找到程式碼範例
返回先前資料以獲得更好的使用者體驗
當根據連續使用者操作進行資料提取時(例如打字時的即時搜尋),保留先前提取的資料可以大幅改善使用者體驗。 keepPreviousData
是一個啟用此行為的選項。以下是一個簡單的搜尋 UI
function Search() {
const [search, setSearch] = React.useState('');
const { data, isLoading } = useSWR(`/search?q=${search}`, fetcher, {
keepPreviousData: true
});
return (
<div>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search..."
/>
<div className={isLoading ? "loading" : ""}>
{data?.products.map(item => <Product key={item.id} name={item.name} />)
</div>
</div>
);
}
啟用 keepPreviousData
後,即使您變更了 SWR 鍵值,並且新鍵值的資料再次開始載入,您仍會取得先前的資料。
您可以在此處找到此範例的完整程式碼:https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m (在新分頁中開啟)。
效能的依賴收集
只有當元件中使用的狀態已更新時,SWR 才會觸發重新渲染。 如果您僅在元件中使用 data
,SWR 會忽略其他屬性(例如 isValidating
和 isLoading
)的更新。 這可以大幅減少渲染次數。 您可以在此處找到更多資訊。