跳到內容
文件
進階
了解 SWR

了解 SWR

狀態機

useSWR 根據 fetcher 函數的狀態,返回 dataerrorisLoadingisValidating。以下圖表描述了 SWR 在某些情境下如何返回值。

提取與重新驗證

此模式用於提取資料並稍後重新驗證。

A pattern for fetch and revalidate

鍵值變更

此模式用於提取資料,變更鍵值,然後稍後重新驗證。

A pattern for key change

鍵值變更 + 先前資料

此模式用於提取資料,變更鍵值,然後使用 keepPreviousData 選項稍後重新驗證。

A pattern for key change + previous data

回退

此模式用於提取資料,並使用回退資料稍後重新驗證。

A pattern for fallback

鍵值變更 + 回退

此模式用於提取資料,變更鍵值,並使用回退資料稍後重新驗證。

A pattern for key change + fallback

鍵值變更 + 先前資料 + 回退

此模式用於提取資料,變更鍵值,並使用 keepPreviousData 選項和回退資料稍後重新驗證。

A pattern for key change + previous data + fallback

結合 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}
    </>
  );
}

An example of using the isLoading state

您可以在此處 (在新分頁中開啟)找到程式碼範例

返回先前資料以獲得更好的使用者體驗

當根據連續使用者操作進行資料提取時(例如打字時的即時搜尋),保留先前提取的資料可以大幅改善使用者體驗。 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 鍵值,並且新鍵值的資料再次開始載入,您仍會取得先前的資料。

當已啟用 keepPreviousData 時,保留先前的搜尋結果

您可以在此處找到此範例的完整程式碼:https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m (在新分頁中開啟)

效能的依賴收集

只有當元件中使用的狀態已更新時,SWR 才會觸發重新渲染。 如果您僅在元件中使用 data,SWR 會忽略其他屬性(例如 isValidatingisLoading)的更新。 這可以大幅減少渲染次數。 您可以在此處找到更多資訊。