action
路由 action
是一个仅服务器端函数,用于处理数据变更和其他操作。如果对您的路由发出了非 GET
请求(DELETE
、PATCH
、POST
或 PUT
),则将在 loader
之前调用操作。
action
的 API 与 loader
相同,唯一的区别是它们的调用时机。这使您能够在一个路由模块中共同定位有关数据集的所有内容:数据读取、渲染数据的组件以及数据写入。
import type { ActionFunctionArgs } from "@remix-run/node"; // or cloudflare/deno
import { json, redirect } from "@remix-run/node"; // or cloudflare/deno
import { Form } from "@remix-run/react";
import { TodoList } from "~/components/TodoList";
import { fakeCreateTodo, fakeGetTodos } from "~/utils/db";
export async function action({
request,
}: ActionFunctionArgs) {
const body = await request.formData();
const todo = await fakeCreateTodo({
title: body.get("title"),
});
return redirect(`/todos/${todo.id}`);
}
export async function loader() {
return json(await fakeGetTodos());
}
export default function Todos() {
const data = useLoaderData<typeof loader>();
return (
<div>
<TodoList todos={data} />
<Form method="post">
<input type="text" name="title" />
<button type="submit">Create Todo</button>
</Form>
</div>
);
}
当对 URL 发出 POST
请求时,路由层次结构中的多个路由将匹配该 URL。与对 loader
发出 GET
请求不同,所有 loader
都被调用以构建 UI,只调用一个操作。
如果您想发布到索引路由,请在操作中使用 ?index
:<Form action="/accounts?index" method="post" />
操作 URL | 路由操作 |
---|---|
/accounts?index |
app/routes/accounts._index.tsx |
/accounts |
app/routes/accounts.tsx |
还要注意,没有 action 属性的表单(<Form method="post">
)将自动发布到渲染它们的同一路由,因此仅当您从索引路由之外的地方发布到索引路由时,使用 ?index
参数来区分父路由和索引路由才有用。如果您从索引路由本身发布到索引路由,或者从父路由本身发布到父路由,则根本不需要定义 <Form action>
,只需省略它:<Form method="post">
。
另请参阅