swr
swr copied to clipboard
infinite: do not revalidate every page on mutate(undefined)
Bug report
Description / Observed Behavior
When I use .mutate(), all pages are revalidated even tough nothing changed in the first page, and the keys didn't change
This behaviour happens regardless of revalidateIfStale
, and regardless of the new revalidateFirstPage
Expected Behavior
Do not revalidate if the first page is the same and keys are the same
Repro Steps / Code Example
const key = useCallback((page: number, previous: Data | null) => {
// First page
if (page === 0 || !previous)
return h(`topics`) // h is just a query builder
// No next page
if (!previous.after)
return null
// Next page
const [after] = previous.after
return h(`topics`, { after })
}, [])
const res = useSWRInfinite<Data>(key, fetcher, {})
const refresh = useCallback(() => {
res.mutate()
}, [res])
return <button onClick={refresh}>
refresh
</button>
Additional Context
happening on both [email protected] and [email protected]
This also happens on automatic revalidation
Ok, this comes to the fact that mutate()
becomes mutate(undefined)
Fix is:
const refresh = useCallback(() => {
res.mutate(d => d, true)
}, [res.mutate])
Still happens on beta 8, all pages are revalidated when doing mutate(undefined)
const refresh = useCallback(() => {
res.mutate(d => d, true)
}, [res.mutate])
Very weird, let me try to reproduce this.
If you call res.mutate()
, everything will be revalidated. That's currently the expected behavior:
https://github.com/vercel/swr/blob/e1677522d86017ec84099f90be03ec9607baf34b/infinite/index.ts#L190-L191
We need to improve the local mutation API for pages a bit.
Hi!
Have there been any updates regarding this issue? I'd like to be able to mutate & revalidate a specified page, and not all the loaded pages when calling mutate()
. Is this possible in any way with the current implementation?
Hi! Any updates regarding this issue?
If you find this annoying, you can use my library
https://github.com/hazae41/xswr
You can revalidate any single page without revalidating everything
I have to use SWR only, but I found some work around. Thanks!
hi @misa-minic could you share your solution? I thought about storing all items into a useState
and then modifying a specific item after it's updated but I feel there should be a better solution
Hi @khanhld1910 Sorry for the late reply, I hope you found the solution by now.
If not, take a look at: https://swr.vercel.app/docs/mutation.en-US#mutate-multiple-items
You should be able with mutate to update only a certain KEY which represents each api call/url for getting a next "page" of items. In my case, I find the index of the item I updated e.g. index 15, then I could say, refetch only 10 items, from index 10 to index 20. This way I am not updating all the fetched items, but only 10 among which is my updated item.
Let me know if you need some info.