);
}
```
Make sure your inputs have names or else the `FormData` will not include that field's value.
All of this will trigger state updates to any rendered [`useNavigation`][usenavigation] hooks so you can build pending indicators and optimistic UI while the async operations are in-flight.
If the form doesn't _feel_ like navigation, you probably want [`useFetcher`][usefetcher].
## `action`
The url to which the form will be submitted, just like [HTML form action][htmlformaction]. The only difference is the default action. With HTML forms, it defaults to the full URL. With `
>
);
}
function ProjectsPage() {
return ;
}
}
action={ProjectsLayout.action}
>
}
action={ProjectsPage.action}
/>
;
```
If the current URL is `"/projects/123"`, the form inside the child
route, `ProjectsPage`, will have a default action as you might expect: `"/projects/123"`. In this case, where the route is the deepest matching route, both `
```
**See also:**
- [Index Search Param][indexsearchparam] (index vs parent route disambiguation)
Please see the [Splat Paths][relativesplatpath] section on the `useResolvedPath` docs for a note on the behavior of the `future.v7_relativeSplatPath` future flag for relative `useNavigate()` behavior within splat routes
## `method`
This determines the [HTTP verb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) to be used. The same as plain HTML [form method][htmlform-method], except it also supports "put", "patch", and "delete" in addition to "get" and "post". The default is "get".
### GET submissions
The default method is "get". Get submissions _will not call an action_. Get submissions are the same as a normal navigation (user clicks a link) except the user gets to supply the search params that go to the URL from the form.
```tsx
```
Let's say the user types in "running shoes" and submits the form. React Router emulates the browser and will serialize the form into [URLSearchParams][urlsearchparams] and then navigate the user to `"/products?q=running+shoes"`. It's as if you rendered a `` as the developer, but instead you let the user supply the query string dynamically.
Your route loader can access these values most conveniently by creating a new [`URL`][url] from the `request.url` and then load the data.
```tsx
{
let url = new URL(request.url);
let searchTerm = url.searchParams.get("q");
return fakeSearchProducts(searchTerm);
}}
/>
```
### Mutation Submissions
All other methods are "mutation submissions", meaning you intend to change something about your data with POST, PUT, PATCH, or DELETE. Note that plain HTML forms only support "post" and "get", we tend to stick to those two as well.
When the user submits the form, React Router will match the `action` to the app's routes and call the `` with the serialized [`FormData`][formdata]. When the action completes, all of the loader data on the page will automatically revalidate to keep your UI in sync with your data.
The method will be available on [`request.method`][requestmethod] inside the route action that is called. You can use this to instruct your data abstractions about the intent of the submission.
```tsx
}
loader={async ({ params }) => {
return fakeLoadProject(params.id);
}}
action={async ({ request, params }) => {
switch (request.method) {
case "PUT": {
let formData = await request.formData();
let name = formData.get("projectName");
return fakeUpdateProject(name);
}
case "DELETE": {
return fakeDeleteProject(params.id);
}
default: {
throw new Response("", { status: 405 });
}
}
}}
/>;
function Project() {
let project = useLoaderData();
return (
<>
>
);
}
```
As you can see, both forms submit to the same route but you can use the `request.method` to branch on what you intend to do. After the actions completes, the `loader` will be revalidated and the UI will automatically synchronize with the new data.
## `navigate`
You can tell the form to skip the navigation and use a [fetcher][usefetcher] internally by specifying `