import { Callout } from 'nextra-theme-docs' import Video from 'components/video'
useSWR
returns data
, error
, isLoading
, and isValidating
depending on the state of the fetcher
function. This diagrams describe how SWR returns values in some scenarios.
This pattern is to fetch data and revalidate it later.
This pattern is to fetch data and change the key and revalidate it later.
This pattern is to fetch data and change the key and revalidate it later with the keepPreviousData
option.
This pattern is to fetch data and revalidate it later with fallback data.
This pattern is to fetch data and change the key and revalidate it later with fallback data.
This pattern is to fetch data and change the key and revalidate it later with the keepPreviousData
option and fallback data.
Combining with isLoading and isValidating for better UX [#combining-with-isloading-and-isvalidating-for-better-ux]
Comparing to the existing isValidating
value, isLoading
is a new property that can help you for the more general loading cases for UX.
isValidating
becomestrue
whenever there is an ongoing request whether the data is loaded or notisLoading
becomestrue
when there is an ongoing request and data is not loaded yet.
Simply saying you can use isValidating
for indicating everytime there is an ongoing revalidation, and isLoading
for indicating that SWR is revalidating but there is no data yet to display.
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}
</>
);
}
You can find the code example here
When doing data fetching based on continuous user actions, e.g. real-time search when typing, keeping the previous fetched data can improve the UX a lot. keepPreviousData
is an option to enable that behavior. Here's a simple search 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>
);
}
With keepPreviousData
enabled, you will still get the previous data even if you change the SWR key and the data for the new key starts loading again.
CleanShot.2022-04-17.at.02.57.44.mp4
You can find the full code for this example here: https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m.
SWR only triggers re-rendering when the states used in the component have been updated. If you only use data
in the component, SWR ignores the updates of other properties like isValidating
, and isLoading
. This reduces rendering counts a lot. More information can be found here.