MENU
Prefetching
Using the usePrefetch() hook, you can prefetch some data to the cache for a page before the user navigates to the page or attempts to load some known content.
If the query exists in the cache, and
- no options are specified, OR
- ifOlderThan evaluates to false,
If ifOlderThan evaluates to true, the query will be performed even if there is an existing cache entry.
function User() {
const prefetchUser = usePrefetch('getUser')
// Low priority hover will not fire unless the last request happened more than 35s ago
// High priority hover will always fire
return (
<div>
<button onMouseEnter={() => prefetchUser(4, { ifOlderThan: 35 })}>
Low priority
</button>
<button onMouseEnter={() => prefetchUser(4, { force: true })}>
High priority
</button>
</div>
);
}
Alternatively, you can do the following to prefetch data:
store.dispatch(
api.util.prefetch(endpointName, arg, { force: false, ifOlderThan: 10 })
)
dispatch(api.endpoints[endpointName].initiate(arg, { forceRefetch: true }))
Eg. prefetching the next page in advance...
const PostList = () => {
const [page, setPage] = useState(1)
const { data: posts, isLoading, isFetching } = useListPostsQuery(page)
const prefetchPage = usePrefetch('listPosts')
const prefetchNext = useCallback(() => {
prefetchPage(page + 1)
}, [prefetchPage, page])
useEffect(() => {
if (page !== posts?.total_pages) {
prefetchNext()
}
}, [posts, page, prefetchNext])
if (isLoading) {
return <div>Loading</div>
}
if (!posts?.data) {
return <div>No posts :(</div>
}
return (
<Box>
<HStack spacing="14px">
<Button
onClick={() => setPage((prev) => prev - 1)}
isLoading={isFetching}
disabled={page === 1}
>
<Icon as={MdArrowBack} />
</Button>
<Button
onClick={() => setPage((prev) => prev + 1)}
isLoading={isFetching}
disabled={page === posts.total_pages}
onMouseEnter={prefetchNext}
>
<Icon as={MdArrowForward} />
</Button>
<Box>{`${page} / ${posts.total_pages}`}</Box>
</HStack>
<List spacing={3} mt={6}>
{posts?.data.map(({ id, title, status }) => (
<ListItem key={id}>
<ListIcon as={MdBook} color="green.500" /> {title}{' '}
<Badge
ml="1"
fontSize="0.8em"
colorScheme={getColorForStatus(status)}
>
{status}
</Badge>
</ListItem>
))}
</List>
</Box>
)
}