Open nekusu opened 1 month ago
Additionally, the Supabase clients I'm using for both the server and the client are set up following this guide: https://supabase.com/docs/guides/auth/server-side/nextjs?queryGroups=router&router=app
did you try to pin-point the cause? cache updates are working in normal circumstances, and I wonder what causes it to break here. if revalidateIfStale: true
causes a revalidation, then the cache item is hit correctly and the update is not being applied. can you show the full code, including how you call the updateUser
mutation? does removing the fallbackData
change anything?
I’ve made some progress on the issue. Here’s what I found:
I noticed that when passing only the fallbackData
directly to the useQuery
hook, the cache was not populated correctly. The SWR cache would only contain the key without any data. This was confirmed by inspecting the cache with:
const { cache } = useSWRConfig();
When fallbackData
is set, the value for the cache key doesn’t include the data, which causes mutations not to work properly. However, when I remove fallbackData
, the cache correctly contains the data and updates as expected.
Instead of passing just fallbackData
to the useQuery
hook, I used both the key and the data returned from fetchQueryFallbackData
and passed them to SWRConfig
(setting fallback
instead of fallbackData
in useQuery
also works). This ensured that the cache was populated correctly and that mutations worked.
It seems that when passing only fallbackData
, SWR treats it as a temporary value for the initial render, but it doesn’t associate the data with the cache key or persist it. As a result, the cache isn’t set properly and subsequent mutations fail to apply. By using the key generated by fetchQueryFallbackData
, the cache is correctly associated with the data, allowing it to be updated by mutations. This issue arises specifically when revalidateIfStale
is set to false
, otherwise the cache would be populated on mount as normally.
I believe this should be corrected in the documentation. Currently, it mentions that you can either pass fallbackData
directly to useSWR
or define it globally in SWRConfig
, but it seems that they don't behave the same way. The correct procedure should be set fallback
on either the useQuery
hook or globally in SWRConfig
.
Let me know if you agree with the analysis, I can do a PR updating the docs!
After further testing I realized that I was wrong about the solution in my previous comment. I was incorrectly setting the fallback
in SWRConfig
.
Initially I was passing it as [string, any]
as returned by the fetchQueryFallbackData
function instead of { [key: string]: any }
, meaning that the fallback was being ignored, causing the cache to not have that initial key and value at all and triggering a revalidation on mount. Once I fixed that and set the fallback correctly, the behavior matched what I observed when using fallbackData
directly in the hook.
This means that currently, neither approach correctly handles the fallback, setting fallback
correctly in SWRConfig
produces the same behavior as setting fallbackData
directly in the hook, the key in the cache is generated but its value isn't populated with the data regardless of where fallback is set and mutations fail to apply.
thanks for the detailed investigation! Did you confirm the same behaviour with using plain swr? I am struggling to find the cause in cache helpers for this.
I ended up using the react-query package. If I remember correctly, the root cause of the issue was that setting fallbackData
in SWR does not prepopulate the cache. As a result, subsequent mutations fail because there is no existing cache data to mutate.
This behavior contrasts with react-query, where you have Initial Query Data and Placeholder Query Data. initialData
is persisted to the cache, while placeholderData
is not. In SWR, fallbackData
behaves similarly to placeholderData
, meaning it only serves as a temporary placeholder when data is undefined
.
Found a comment that proves this: https://github.com/vercel/swr/issues/2114#issuecomment-1327657957
Describe the bug
When using mutation hooks with fallback data set in the
useQuery
hook, the cache does not update after triggering a mutation. Specifically, after passing fallback data touseQuery
viafetchQueryFallbackData
,useUpdateMutation
doesn't seem to update the cache as expected.To Reproduce
Steps to reproduce the behavior:
Implement
useQuery
withfallbackData
as shown in the example below:useUpdateMutation
to update a user record:Expected behavior
The cache should be updated after a mutation when using
useQuery
withfallbackData
.Additional context
revalidateIfStale: true
, either directly in the hook or globally viaSWRConfig
, resolves the issue and updates the cache as expected.