trpc optimistic updates causing data flicker
I'm trying to add optimistic updates to a calendar component but when the mutate function is called there's a flicker in the existing events
3 Replies
const utils = api.useUtils();
const { data: events } = api.entries.getByMonth.useQuery(
{ workspaceId, monthDate: format(month, "yyyy/MM") },
{
initialData,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
},
);
const { mutate } = api.entries.update.useMutation({
onMutate: async (input) => {
await utils.entries.getByMonth.cancel();
const prev = utils.entries.getByMonth.getData({ workspaceId, monthDate });
if (!prev || !auth) return;
const updatedEvent = {
...prev.find((e) => e.id === input.id)!,
...input,
temp: true,
};
utils.entries.getByMonth.setData({ workspaceId, monthDate }, (prevState) => {
if (!prevState) return [];
return [...prevState.filter((e) => e.id !== updatedEvent.id), updatedEvent];
});
return () => utils.entries.getByMonth.setData({ workspaceId, monthDate }, prev);
},
onSettled: () => {
return utils.entries.getByMonth.invalidate({
workspaceId,
monthDate,
});
},
onError: (error, _variables, rollback) => {
toast.error("Something happened, please try again!", {
description: error.message,
});
if (rollback) {
rollback();
}
},
});
const utils = api.useUtils();
const { data: events } = api.entries.getByMonth.useQuery(
{ workspaceId, monthDate: format(month, "yyyy/MM") },
{
initialData,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
},
);
const { mutate } = api.entries.update.useMutation({
onMutate: async (input) => {
await utils.entries.getByMonth.cancel();
const prev = utils.entries.getByMonth.getData({ workspaceId, monthDate });
if (!prev || !auth) return;
const updatedEvent = {
...prev.find((e) => e.id === input.id)!,
...input,
temp: true,
};
utils.entries.getByMonth.setData({ workspaceId, monthDate }, (prevState) => {
if (!prevState) return [];
return [...prevState.filter((e) => e.id !== updatedEvent.id), updatedEvent];
});
return () => utils.entries.getByMonth.setData({ workspaceId, monthDate }, prev);
},
onSettled: () => {
return utils.entries.getByMonth.invalidate({
workspaceId,
monthDate,
});
},
onError: (error, _variables, rollback) => {
toast.error("Something happened, please try again!", {
description: error.message,
});
if (rollback) {
rollback();
}
},
});
this is the flicker I'm referring to when updating an entry