Fix outfit saving infinite loop in error case

Really don't know why this wasn't a problem with Apollo (or was it??),
but yeah, don't save when there's a save error!! Then we reset the
mutation state when the outfit state changes.
This commit is contained in:
Emi Matchu 2023-11-06 12:54:23 -08:00
parent f8bcf5a0de
commit 47ea796af4

View file

@ -12,10 +12,6 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
const navigate = useNavigate(); const navigate = useNavigate();
const toast = useToast(); const toast = useToast();
// There's not a way to reset an Apollo mutation state to clear out the error
// when the outfit changes… so we track the error state ourselves!
const [saveError, setSaveError] = React.useState(null);
// Whether this outfit is new, i.e. local-only, i.e. has _never_ been saved // Whether this outfit is new, i.e. local-only, i.e. has _never_ been saved
// to the server. // to the server.
const isNewOutfit = outfitState.id == null; const isNewOutfit = outfitState.id == null;
@ -62,6 +58,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
}, },
}); });
const isSaving = saveOutfitMutation.isPending; const isSaving = saveOutfitMutation.isPending;
const saveError = saveOutfitMutation.error;
const saveOutfitFromProvidedState = React.useCallback( const saveOutfitFromProvidedState = React.useCallback(
(outfitState) => { (outfitState) => {
@ -85,7 +82,6 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
}) })
.catch((e) => { .catch((e) => {
console.error(e); console.error(e);
setSaveError(e);
toast({ toast({
status: "error", status: "error",
title: "Sorry, there was an error saving this outfit!", title: "Sorry, there was an error saving this outfit!",
@ -131,6 +127,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
!isNewOutfit && !isNewOutfit &&
canSaveOutfit && canSaveOutfit &&
!isSaving && !isSaving &&
!saveError &&
debouncedOutfitStateIsSaveable && debouncedOutfitStateIsSaveable &&
!outfitStatesAreEqual(debouncedOutfitState, outfitState.savedOutfitState) !outfitStatesAreEqual(debouncedOutfitState, outfitState.savedOutfitState)
) { ) {
@ -145,6 +142,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
isNewOutfit, isNewOutfit,
canSaveOutfit, canSaveOutfit,
isSaving, isSaving,
saveError,
debouncedOutfitState, debouncedOutfitState,
debouncedOutfitStateIsSaveable, debouncedOutfitStateIsSaveable,
outfitState.savedOutfitState, outfitState.savedOutfitState,
@ -154,9 +152,11 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
// When the outfit changes, clear out the error state from previous saves. // When the outfit changes, clear out the error state from previous saves.
// We'll send the mutation again after the debounce, and we don't want to // We'll send the mutation again after the debounce, and we don't want to
// show the error UI in the meantime! // show the error UI in the meantime!
React.useEffect(() => { const resetMutation = saveOutfitMutation.reset;
setSaveError(null); React.useEffect(
}, [outfitState.outfitStateWithoutExtras]); () => resetMutation(),
[outfitState.outfitStateWithoutExtras, resetMutation],
);
return { return {
canSaveOutfit, canSaveOutfit,