-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mutate() and the deduping interval #1417
Comments
could you try |
I tried and it doesn't revalidate, but I want it to revalidate if the stale data is older than the deduping interval |
dedupingInterval is the time between two revalidate not the time between mutate and revalidate.
if you want to send less requests, revalidateIfStale could save one request when hook mounted. |
There should be a time between mutate a revalidate then |
I have this same issue. Here's my use case: I'm on React Native and am wrapping fwiw I was able to solve this using undocumented so this does what I want it to do: function useSomeData({ paused }) {
const readData = useSwr("some/key", myFetcher, { isPaused: () => paused })
const { revalidate, mutate } = readData
useEffect(() => {
// @ts-ignore dedupe is a revalidation option but not included on the type: https://github.com/vercel/swr/blob/0.5.6/src/use-swr.ts#L360
if (!paused) revalidate({ dedupe: true })
// note that calling 'mutate' here would make an api request for _each instance_ consuming this hook. I don't want that.
// mutate()
}, [paused, revalidate])
} However, since |
This doesn't sound correct to me. |
BTW from your code snippet, I suppose the new hook in #1262 is what you need. @computerjazz |
Thanks @promer94 and @shuding ! So, here's a more complete example of my use case: https://stackblitz.com/edit/nextjs-4xtgyg?file=pages%2Findex.js Notice that if the fetch starts as The new hook in #1262 looks like it may solve the issue as long as it deduplicates correctly, but I wonder if this specific case should be handled within the And apologies if I'm steering this issue too far away from the original report. I'd be happy to open a new issue and move discussion there. |
I also feel that it makes sense to dedupe all It feels like a pretty common pattern to ingest the same hook in multiple components, and allow SWR to handle the de-duping to avoid unnecessary re-renders. In React-Native, you have to handle const useProfile = () => {
const swr = useSwr('/users/me');
useFocusEffect(() => swr.mutate());
return swr;
}
const Profile = () => {
const { data } = useProfile();
return <ProfileHeader />
}
const ProfileHeader = () => {
const { data } = useProfile();
return <Foo />
} Standard fetching is deduped correctly, and that's the biggest selling point of SWR for me. However, with this custom revalidation on focus for react-native, every call to In this example, two requests are being sent out, when I would expect them to be deduped. I don't really think it has anything to do with |
For those who don't want to scratch their heads anymore, wondering why the fuck swr does this, I made my own library. https://github.com/hazae41/xswr It uses composition-based hooks and has a very easy learning curve, and 0% weird behaviour. |
I thought I was going mad, but turns out this is actually a thing. Why aren't mutate calls deduped too?! |
I also have a similar problem, in the case of |
I came here searching to make sure that Perhaps a middle ground is to have |
I am also trying to make mutate actually dedupe the requests. Is it possible? I have a revalidateOnFocus middleware for react-native which currently causes 60 requests as its used in a list of 60 components. The default behavor works as useSWR only is called once as the key is the same, but trying to mutate the hooks based on focus will not dedupe. |
Honestly, pretty easy solution with const dedupeCache = new Map();
export const revalidateOnFocus: Middleware = (useSWRNext) => {
return (key, fn, config) => {
const swr = useSWRNext(key, fn, config);
useFocusEffect(
useCallback(() => {
if (typeof swr.data === "undefined") return;
const serializedKey = unstable_serialize(key);
if (dedupeCache.has(serializedKey)) return;
dedupeCache.set(serializedKey, true);
swr.mutate().finally(() => {
dedupeCache.delete(serializedKey);
});
}, [swr.data, swr.mutate]),
);
return swr;
};
};
// Your query
const {data} = useSWR("/path", {
use: [revalidateOnFocus]
})
// Or global
<SWRConfig value={{ use: [revalidateOnFocus] }}>
{children}
</SWRConfig> |
Bug report
Description / Observed Behavior
I prefetch and mutate some data when the user hovers a link using
mutate(key, data, false)
When the user clicks the link, the page is loaded and useSWR revalidates the data.
However, the hover and the click where made within deduping interval.
Expected Behavior
Do not revalidate if
mutate(key, data, false)
has been called within the deduping intervalRepro Steps / Code Example
Additional Context
[email protected]
The text was updated successfully, but these errors were encountered: