From 8da9aa29198c9c65615545721b642e080f44fc9e Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Tue, 14 Nov 2023 09:03:42 -0500 Subject: [PATCH] Fix useFormAction inheriting ?index param from child route action submission --- .changeset/form-action-index.md | 5 +++++ .../__tests__/data-browser-router-test.tsx | 22 +++++++++++++++++++ packages/react-router-dom/index.tsx | 10 ++++----- 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 .changeset/form-action-index.md diff --git a/.changeset/form-action-index.md b/.changeset/form-action-index.md new file mode 100644 index 0000000000..5d4929f2d1 --- /dev/null +++ b/.changeset/form-action-index.md @@ -0,0 +1,5 @@ +--- +"react-router-dom": patch +--- + +Fix `useFormAction` which was incorrectly inheriting the `?index` query param from child route `action` submissions diff --git a/packages/react-router-dom/__tests__/data-browser-router-test.tsx b/packages/react-router-dom/__tests__/data-browser-router-test.tsx index 574b653816..5f0ce3faf5 100644 --- a/packages/react-router-dom/__tests__/data-browser-router-test.tsx +++ b/packages/react-router-dom/__tests__/data-browser-router-test.tsx @@ -2693,6 +2693,28 @@ function testDomRouter( "/foo" ); }); + + it("does not include the index parameter if we've submitted to a child index route", async () => { + let router = createTestRouter( + createRoutesFromElements( + + + }> + Index} /> + + + + ), + { + window: getWindow("/foo/bar?index&a=1"), + } + ); + let { container } = render(); + + expect(container.querySelector("form")?.getAttribute("action")).toBe( + "/foo/bar?a=1" + ); + }); }); describe("index routes", () => { diff --git a/packages/react-router-dom/index.tsx b/packages/react-router-dom/index.tsx index c86eb8286f..78b6d8db96 100644 --- a/packages/react-router-dom/index.tsx +++ b/packages/react-router-dom/index.tsx @@ -1551,11 +1551,11 @@ export function useFormAction( // would have called useResolvedPath(".") which will never include a search path.search = location.search; - // When grabbing search params from the URL, remove the automatically - // inserted ?index param so we match the useResolvedPath search behavior - // which would not include ?index - if (match.route.index) { - let params = new URLSearchParams(path.search); + // When grabbing search params from the URL, remove any included ?index param + // since it might not apply to our contextual route. We add it back based + // on match.route.index below + let params = new URLSearchParams(path.search); + if (params.has("index") && params.get("index") === "") { params.delete("index"); path.search = params.toString() ? `?${params.toString()}` : ""; }