swr
swr copied to clipboard
Global mutate with cache provider unexpectedly provides undefined for optimisticData callback
Bug report
Description / Observed Behavior
I'm seeing that, in specific configurations, using global mutate
unexpectedly provides undefined
for the old value in an optimisticData
callback.
Expected Behavior
I expected global mutate
to behave similarly to a bound mutate
with the same key. This is what the documentation suggests (with the caveat that "mounted SWR hook using the same key" is satisfied)
Either switching to a bound mutate
(which would require restructuring a lot of my code), or disabling the cache provider (which would significantly impact UX), both cause the optimisticData
callback to correctly provide the old value.
Repro Steps / Code Example
https://codesandbox.io/s/distracted-leavitt-kgjpk4?file=/src/App.js
Observe that clicking "Bound mutate" increments the counter, but "Global mutate" does not (because, at the very least, the old
value provided in optimisticData
is surprisingly undefined
rather than the current value of the counter). If you comment out SWRConfig
provider config on line 44, provider: () => cache
, then both buttons work.
Additional Context
Affects at least swr 2.2.4 and 2.2.2.
The root cause may be the same as https://github.com/vercel/swr/issues/2701 or https://github.com/vercel/swr/issues/2799. The shape of this is slightly different from those PRs' descriptions, so I figured I'd file this separately.
@sartak Thank you for reporting this. You are right. Optimistic updating by the global mutate doesn't work with custom cache providers. We should fix this or document it as a limitation of the custom cache provider.
UPDATE: We already have documented it as a warning. Our current recommendation is to use mutate
returned from useSWRConfig()
rather than the global mutate
.
https://swr.vercel.app/docs/advanced/cache#create-cache-provider
It's unfortunate that these two features are subtly broken when used together.