-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
The documentation for mutate talks about local mutation for faster feedback, but the documented way to use it only mutates after a promise has resolved - in other words, not immediately.
As a result, I've found myself writing code in this kind of pattern:
mutate(path, { ...data, patch }, false); // mutate immediately, don't revalidate
await patchData(patch); // await the actual API call
trigger(path); // trigger revalidation afterwardsTechnically, if patchData also returns the full new data, you could also do it like this:
mutate(path, { ...data, patch }, false); // mutate immediately locally, don't revalidate
mutate(path, patchData(patch), false); // update with API-backed result from patchDataWhich is actually also present in the documentation. But it is kinda janky to need two subsequent mutate calls for this...
One backwards-compatible way to deal with this could be to extend mutate to accept options as the third parameter, and introduce initialData much like present in useSWR. Then you could do something like this:
// mutate immediately with `initialData`,
// then replace with result from patchData when it resolves
mutate(path, patchData(patch), { initialData: { ...data, patch }); In case the patchData function (or equivalent) doesn't return the full data, the third argument could also be augmented to accept a Promise, eg.
// wait until the Promise from patchData resolves before triggering revalidate
mutate(path, { ...data, patch }, patchData(patch))I feel both these changes would make using mutate a lot more ergonomic overall.
In addition, I haven't checked the code to see how easy this would be to implemented, but another nice possibility would be to keep the local data (ie. non-promise second argument if third arg is a promise, anything in initialData) provided to mutate in some sort of "unverified cache", such that in case the provided promises throw, SWR could automatically roll the data back to "last known good value" (ie. the last real API response for that path).