erquhart
erquhart16mo ago

Passing extra values to optimistic updates

Is there a recommended way of passing "extra" data to optimistic updates? Fairly often a mutation result requires more than the inputs, it'd be nice to pass that data (if available) to mutations that use optimistic updates. For now I've been writing functions to pass the extra data into, and having those return the optimistic updater.
6 Replies
ballingt
ballingt16mo ago
If this extra data doesn't depend on the arguments then when you define the optimistic update you can close over additional values:
const defaultValue = 100;
const increment = useMutation(api.counter.increment).withOptimisticUpdate(
(localStore, args) => {
const { increment } = args;
const currentValue = localStore.getQuery(api.counter.get);
if (currentValue !== undefined) {
localStore.setQuery(api.counter.get, {}, currentValue + increment);
} else {
localStore.setQuery(api.counter.get, {}, defaultValue)
}
}
);
const defaultValue = 100;
const increment = useMutation(api.counter.increment).withOptimisticUpdate(
(localStore, args) => {
const { increment } = args;
const currentValue = localStore.getQuery(api.counter.get);
if (currentValue !== undefined) {
localStore.setQuery(api.counter.get, {}, currentValue + increment);
} else {
localStore.setQuery(api.counter.get, {}, defaultValue)
}
}
);
However if it's the same callback that you want to pass different data to then yes, you'll need to take these as arguments to the mutation and not use them on the server. Note that .withOptimisticUpdate() doesn't define a global optimistic update for this mutation, it just returns a mutation runner that also has this effect. So you can build the right optimistic update on demand.
erquhart
erquhartOP16mo ago
not use them on the server
Of course, just add them as args and don't use them 🤦‍♂️ I don't close over because the updaters tend to get pretty involved, so they're defined outside of the components. But yeah, I can just add them as args 🙂
ballingt
ballingt16mo ago
An factory pattern could work here too re code organization concerns,
// could wrap this stuff up in a hook
const increment = useMutation(api.counter.increment).withOptimisticUpdate(buildIncrementUpdate(additionalData));
// could wrap this stuff up in a hook
const increment = useMutation(api.counter.increment).withOptimisticUpdate(buildIncrementUpdate(additionalData));
The downside of adding parameters is that this data will be serialized and send to the server. But it seems like the simplest approach, if the data isn't large this seems nice.
erquhart
erquhartOP16mo ago
The factory pattern is what I'm currently doing, and it does work well.
ballingt
ballingt16mo ago
ah
For now I've been writing functions to pass the extra data into, and having those return the optimistic updater.
that makes sense 🤦‍♂️
erquhart
erquhartOP16mo ago
I should have just said factory lol

Did you find this page helpful?