了解 SWR
状态机
useSWR
返回 data
, error
, isLoading
和 isValidating
,具体取决于 fetcher
函数的状态。这些图描述了 SWR 在某些情况下如何返回值。
获取和重新验证
此模式用于获取数据并在稍后重新验证。
键更改
此模式用于获取数据,更改键并在稍后重新验证。
键更改 + 先前数据
此模式用于获取数据,更改键并在稍后使用 keepPreviousData
选项重新验证。
回退
此模式用于获取数据并在稍后使用回退数据重新验证。
键更改 + 回退
此模式用于获取数据,更改键并在稍后使用回退数据重新验证。
键更改 + 先前数据 + 回退
此模式用于获取数据,更改键并在稍后使用 keepPreviousData
选项和回退数据重新验证。
结合 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}
</>
);
}
您可以在此处找到代码示例 此处 (在新标签页中打开)
返回先前数据以获得更好的 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 键且新键的数据开始重新加载,您仍然会获得先前的数据。
您可以在此处找到此示例的完整代码: https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m (在新标签页中打开).
依赖项收集以提高性能
SWR 仅在组件中使用的状态更新后才会触发重新渲染。如果您仅在组件中使用 data
,SWR 会忽略其他属性(如 isValidating
和 isLoading
)的更新。这大大减少了渲染次数。更多信息可以在 此处找到。