Race condition with optimistic useSWRMutation
Unanswered
Florian posted this in #help-forum
FlorianOP
I made an optimistic favorite button with
How can I avoid this?
useSWRMutation. If I click the button multiple times fast in a row, I sometimes get a race condition and the button toggles back to the opposite state.How can I avoid this?
1 Reply
FlorianOP
const { data } = useSWR<{ isFavoritedByUser: boolean }>(
`/api/companions/${companionId}/favorites`,
async (url: string) => {
const response = await fetch(url);
if (!response.ok) {
throw new Error("Failed to fetch favorites info");
}
return response.json();
},
{
revalidateOnFocus: false,
revalidateOnReconnect: false,
revalidateOnMount: false,
revalidateIfStale: false,
fallbackData: { isFavoritedByUser: initialIsFavoritedByUser },
onError(err) {
console.error(err);
toast({
variant: "destructive",
description: "Failed to fetch favorites info. Please try again.",
});
},
}
);
const { trigger } = useSWRMutation<{ isFavoritedByUser: boolean }>(
`/api/companions/${companionId}/favorites`,
async (url: string) => {
if (!data) return;
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ favorite: !data.isFavoritedByUser }),
});
if (!response.ok) {
throw new Error("Failed to update favorite status");
}
return response.json();
},
{
rollbackOnError: true,
optimisticData: {
isFavoritedByUser: !data?.isFavoritedByUser,
},
populateCache(result, currentData) {
return {
...currentData,
...result,
};
},
revalidate: false,
onError(err) {
console.error(err);
toast({
variant: "destructive",
description: "Failed to update favorite status. Please try again.",
});
},
}
);
function handleClick() {
trigger();
toast({
description:
"Companion " +
(data?.isFavoritedByUser
? "removed from favorites"
: "added to favorites"),
});
}