Skip to content

Commit 5e98140

Browse files
fix: honor the relative option in useSubmit and fetcher.submit (#15400)
* fix: honor the relative option in useSubmit and fetcher.submit * Updates --------- Co-authored-by: Matt Brophy <matt@brophy.org>
1 parent 91b1911 commit 5e98140

3 files changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Properly respect the `relative` option in `useSubmit`/`fetcher.submit` when resolivng the `action` path

packages/react-router/__tests__/dom/data-browser-router-test.tsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4132,6 +4132,100 @@ function testDomRouter(
41324132
});
41334133
});
41344134

4135+
describe('submit() with relative="path"', () => {
4136+
it("submits relative to the URL for navigations", async () => {
4137+
let router = createTestRouter(
4138+
[
4139+
{
4140+
path: "inbox",
4141+
action: () => "INDEX",
4142+
children: [
4143+
{
4144+
path: "messages",
4145+
action: () => "MESSAGES",
4146+
Component() {
4147+
let actionData = useActionData();
4148+
return <p>{actionData}</p>;
4149+
},
4150+
},
4151+
{
4152+
path: "messages/:id",
4153+
Component() {
4154+
let submit = useSubmit();
4155+
return (
4156+
<button
4157+
onClick={() =>
4158+
submit(
4159+
{ a: "1" },
4160+
{ method: "post", action: "..", relative: "path" },
4161+
)
4162+
}
4163+
>
4164+
Submit
4165+
</button>
4166+
);
4167+
},
4168+
},
4169+
],
4170+
},
4171+
],
4172+
{ window: getWindow("/inbox/messages/1") },
4173+
);
4174+
render(<RouterProvider router={router} />);
4175+
4176+
fireEvent.click(screen.getByText("Submit"));
4177+
await waitFor(() => screen.getByText("MESSAGES"));
4178+
expect(router.state.location.pathname).toBe("/inbox/messages");
4179+
});
4180+
4181+
it("submits relative to the URL for fetchers", async () => {
4182+
let router = createTestRouter(
4183+
[
4184+
{
4185+
path: "inbox",
4186+
action: () => "INDEX",
4187+
children: [
4188+
{
4189+
path: "messages",
4190+
action: () => "MESSAGES",
4191+
},
4192+
{
4193+
path: "messages/:id",
4194+
Component() {
4195+
let fetcher = useFetcher();
4196+
return (
4197+
<>
4198+
<button
4199+
onClick={() =>
4200+
fetcher.submit(
4201+
{ a: "1" },
4202+
{
4203+
method: "post",
4204+
action: "..",
4205+
relative: "path",
4206+
},
4207+
)
4208+
}
4209+
>
4210+
Submit
4211+
</button>
4212+
{fetcher.data ? <p>{fetcher.data}</p> : null}
4213+
</>
4214+
);
4215+
},
4216+
},
4217+
],
4218+
},
4219+
],
4220+
{ window: getWindow("/inbox/messages/1") },
4221+
);
4222+
render(<RouterProvider router={router} />);
4223+
4224+
fireEvent.click(screen.getByText("Submit"));
4225+
await waitFor(() => screen.getByText("MESSAGES"));
4226+
});
4227+
});
4228+
41354229
describe("useSubmit/Form FormData", () => {
41364230
it("gathers form data on <Form> submissions", async () => {
41374231
let actionSpy = jest.fn();

packages/react-router/lib/dom/lib.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,7 @@ export function useSubmit(): SubmitFunction {
26032603
await routerFetch(key, currentRouteId, options.action || action, {
26042604
defaultShouldRevalidate: options.defaultShouldRevalidate,
26052605
preventScrollReset: options.preventScrollReset,
2606+
relative: options.relative,
26062607
formData,
26072608
body,
26082609
formMethod: options.method || (method as HTMLFormMethod),
@@ -2613,6 +2614,7 @@ export function useSubmit(): SubmitFunction {
26132614
await routerNavigate(options.action || action, {
26142615
defaultShouldRevalidate: options.defaultShouldRevalidate,
26152616
preventScrollReset: options.preventScrollReset,
2617+
relative: options.relative,
26162618
formData,
26172619
body,
26182620
formMethod: options.method || (method as HTMLFormMethod),

0 commit comments

Comments
 (0)