Skip to content

Commit 5b6de0d

Browse files
authored
Add action docs on multiple actions (#10527)
1 parent edf1dfc commit 5b6de0d

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

docs/route/action.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,62 @@ You can `throw` in your action to break out of the current call stack (stop runn
129129

130130
For more details and expanded use cases, read the [errorElement][errorelement] documentation.
131131

132+
## Handling multiple actions per route
133+
134+
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 `<button type="submit">` and use that in the action to decide which code to execute (that's right - submitting [buttons][button] can have name/value attributes!):
135+
136+
```jsx lines=[3,5,10,30-32,42-44]
137+
async function action({ request }) {
138+
let formData = await request.formData();
139+
let intent = formData.get("intent");
140+
141+
if (intent === "edit") {
142+
await editSong(formData);
143+
return { ok: true };
144+
}
145+
146+
if (intent === "add") {
147+
await addSong(formData);
148+
return { ok: true };
149+
}
150+
151+
throw json(
152+
{ message: "Invalid intent" },
153+
{ status: 400 }
154+
);
155+
}
156+
157+
function Component() {
158+
let song = useLoaderData();
159+
160+
// When the song exists, show an edit form
161+
if (song) {
162+
return (
163+
<Form method="post">
164+
<p>Edit song lyrics:</p>
165+
{/* Edit song inputs */}
166+
<button type="submit" name="intent" value="edit">
167+
Edit
168+
</button>
169+
</Form>
170+
);
171+
}
172+
173+
// Otherwise show a form to add a new song
174+
return (
175+
<Form method="post">
176+
<p>Add new lyrics:</p>
177+
{/* Add song inputs */}
178+
<button type="submit" name="intent" value="add">
179+
Add
180+
</button>
181+
</Form>
182+
);
183+
}
184+
```
185+
186+
If a button name/value isn't right for your use case, you could also use a hidden input to send and `intent` or you could submit different HTTP methods via the [`<Form method>`][form-method] prop (`POST` for add, `PUT`/`PATCH` for edit, `DELETE` for remove).
187+
132188
[loader]: ./loader
133189
[pickingarouter]: ../routers/picking-a-router
134190
[dynamicsegments]: ./route#dynamic-segments
@@ -146,3 +202,5 @@ For more details and expanded use cases, read the [errorElement][errorelement] d
146202
[useactiondata]: ../hooks/use-action-data
147203
[returningresponses]: ./loader#returning-responses
148204
[createbrowserrouter]: ../routers/create-browser-router
205+
[button]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button
206+
[form-method]: ../components/form#method

0 commit comments

Comments
 (0)