fix: prevent useBlocker from intercepting same-route form submissions (#443)
useBlocker was receiving a boolean, which caused it to block the settings form's own POST submission before the onSubmit state-clear could propagate. Switching to a BlockerFunction that checks nextLocation.pathname lets same-URL form posts through, so the "leave without saving?" dialog only fires on genuine navigation away from the settings page. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c71eb69648
commit
f258d7a304
1 changed files with 9 additions and 3 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
import { Form, useBeforeUnload, useBlocker, useNavigation } from "react-router";
|
import { Form, useBeforeUnload, useBlocker, useLocation, useNavigation, type BlockerFunction } from "react-router";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import {
|
import {
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
|
|
@ -119,6 +119,7 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone
|
||||||
} = loaderData;
|
} = loaderData;
|
||||||
|
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
|
const location = useLocation();
|
||||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||||
const [mobileView, setMobileView] = useState<"grid" | "section">("grid");
|
const [mobileView, setMobileView] = useState<"grid" | "section">("grid");
|
||||||
const [activeSection, setActiveSection] = useState<SettingsSectionId>("league-basics");
|
const [activeSection, setActiveSection] = useState<SettingsSectionId>("league-basics");
|
||||||
|
|
@ -202,7 +203,12 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone
|
||||||
const isSubmittingSettings = navigation.state === "submitting" && updateIntent === "update";
|
const isSubmittingSettings = navigation.state === "submitting" && updateIntent === "update";
|
||||||
const isSubmittingDraftOrder = navigation.state === "submitting" && updateIntent === "set-draft-order";
|
const isSubmittingDraftOrder = navigation.state === "submitting" && updateIntent === "set-draft-order";
|
||||||
const shouldWarnUnsaved = (hasUnsavedSettingsChanges || hasDraftOrderChanges) && !isSubmittingSettings && !isSubmittingDraftOrder;
|
const shouldWarnUnsaved = (hasUnsavedSettingsChanges || hasDraftOrderChanges) && !isSubmittingSettings && !isSubmittingDraftOrder;
|
||||||
const blocker = useBlocker(shouldWarnUnsaved);
|
const blocker = useBlocker(
|
||||||
|
useCallback<BlockerFunction>(
|
||||||
|
({ nextLocation }) => shouldWarnUnsaved && nextLocation.pathname !== location.pathname,
|
||||||
|
[shouldWarnUnsaved, location.pathname]
|
||||||
|
)
|
||||||
|
);
|
||||||
const inviteUrl = season?.inviteCode
|
const inviteUrl = season?.inviteCode
|
||||||
? `${typeof window !== "undefined" ? window.location.origin : ""}/i/${season.inviteCode}`
|
? `${typeof window !== "undefined" ? window.location.origin : ""}/i/${season.inviteCode}`
|
||||||
: "";
|
: "";
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue