---
title: action
new: true
---
# `action`
Route actions are the "writes" to route [loader][loader] "reads". They provide a way for apps to perform data mutations with simple HTML and HTTP semantics while React Router abstracts away the complexity of asynchronous UI and revalidation. This gives you the simple mental model of HTML + HTTP (where the browser handles the asynchrony and revalidation) with the behavior and UX capabilities of modern SPAs.
This feature only works if using a data router, see [Picking a Router][pickingarouter]
```tsx
}
action={async ({ params, request }) => {
let formData = await request.formData();
return fakeUpdateSong(params.songId, formData);
}}
loader={({ params }) => {
return fakeGetSong(params.songId);
}}
/>
```
Actions are called whenever the app sends a non-get submission ("post", "put", "patch", "delete") to your route. This can happen in a few ways:
```tsx
// forms
;
;
// imperative submissions
let submit = useSubmit();
submit(data, {
method: "delete",
action: "/songs/123",
});
fetcher.submit(data, {
method: "patch",
action: "/songs/123/edit",
});
```
## `params`
Route params are parsed from [dynamic segments][dynamicsegments] and passed to your action. This is useful for figuring out which resource to mutate:
```tsx
{
return fakeDeleteProject(params.projectId);
}}
/>
```
## `request`
This is a [Fetch Request][request] instance being sent to your route. The most common use case is to parse the [FormData][formdata] from the request
```tsx
{
let formData = await request.formData();
// ...
}}
/>
```
> A Request?!
It might seem odd at first that actions receive a "request". Have you ever written this line of code?
```tsx [3]
;
// accessed by the same names
formData.get("songTitle");
formData.get("lyrics");
```
For more information on `formData` see [Working with FormData][workingwithformdata].
### Opt-in serialization types
Note that when using [`useSubmit`][usesubmit] you may also pass `encType: "application/json"` or `encType: "text/plain"` to instead serialize your payload into `request.json()` or `request.text()`.
## Returning Responses
While you can return anything you want from an action and get access to it from [`useActionData`][useactiondata], you can also return a web [Response][response].
For more information, see the [loader documentation][returningresponses].
## Throwing in Actions
You can `throw` in your action to break out of the current call stack (stop running the current code) and React Router will start over down the "error path".
```tsx [10]
{
const res = await fetch(
`/api/properties/${params.id}`,
{
method: "put",
body: await request.formData(),
}
);
if (!res.ok) throw res;
return { ok: true };
}}
/>
```
For more details and expanded use cases, read the [errorElement][errorelement] documentation.
## Handling multiple actions per route
A fairly common question that pops up is _"What if I need to handle multiple different behaviors in my action?"_ There's a few ways to accomplish this, but usually the simplest is to put a `name`/`value` on your `