Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(remix-react): Preserve search string in form action when action prop is omitted #3697

Merged
merged 15 commits into from
Aug 10, 2022
Prev Previous commit
Next Next commit
differentiate between no action and '.'
Co-authored-by: Ionut Botizan <ionut.botizan@haufe-lexware.com>
  • Loading branch information
chaance and Ionut Botizan committed Aug 4, 2022

Verified

This commit was signed with the committer’s verified signature.
aroralanuk Kunal Arora
commit 783c43573f37bb89e1cf25be5ec87b72aee5186f
36 changes: 13 additions & 23 deletions packages/remix-react/components.tsx
Original file line number Diff line number Diff line change
@@ -994,36 +994,26 @@ export function useFormAction(
method: FormMethod = "get"
): string {
let { id } = useRemixRouteContext();
let resolvedPath = useResolvedPath(action ?? ".");

// The documented behavior of a form without an explicit action prop is:
// - Forms without an action prop (<Form method="post">) will automatically
// post to the same route within which they are rendered.
//
// The problem with setting the default action to `.` is that
// `useResolvedPath(".")` excludes search params. This is the intended
// behavior of useResolvedPath, but it's unexpected for forms without an
// action prop since the search params are an important part of the current
// location, and the action function should receive those in the request URL.
//
// If the action prop is omitted, we'll append the current route's search
// string to the current location if it exists. If the action is explicitly
// set to `.` it will resolve without the search params to match the intended
// behavior of useResolvedPath, resolving the same URL as `<Link to="." />`
// Previously we set the default action to ".". The problem with this is that
// `useResolvedPath(".")` excludes search params and the hash of the resolved
// URL. This is the intended behavior of when "." is specifically provided as
// the form action, but inconsistent w/ browsers when the action is omitted.
// https://github.com/remix-run/remix/issues/927
let { search: currentSearch } = useLocation();
let actionIsCurrentRoute = action === undefined || action === ".";
let path = useResolvedPath(
action === undefined ? { pathname: ".", search: currentSearch } : action
);
let location = useLocation();
let { search, hash } = resolvedPath;
if (action === undefined) {
search = location.search;
hash = location.hash;
}

let search = path.search;
let isIndexRoute = id.endsWith("/index");

if (actionIsCurrentRoute && isIndexRoute) {
if ((action === undefined || action === ".") && isIndexRoute) {
chaance marked this conversation as resolved.
Show resolved Hide resolved
search = search ? search.replace(/^\?/, "?index&") : "?index";
}

return path.pathname + search;
return resolvedPath.pathname + search + hash;
}

export interface SubmitOptions {