跳至内容
文档
高级
了解 SWR

了解 SWR

状态机

useSWR 返回 data, error, isLoadingisValidating,具体取决于 fetcher 函数的状态。这些图描述了 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 以获得更好的 UX

与现有的 isValidating 值相比,isLoading 是一个新属性,可以帮助您处理更通用的 UX 加载情况。

  • 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

您可以在此处找到代码示例 此处 (在新标签页中打开)

返回先前数据以获得更好的 UX

在执行基于连续用户操作的数据获取时,例如在键入时进行实时搜索,保留先前获取的数据可以极大地改善 UX。 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)的更新。这大大减少了渲染次数。更多信息可以在 此处找到。