操作

action

观看 📼 Remix 单曲: 使用 Form + action 进行数据变更多个表单和单个按钮变更

路由 action 是一个仅服务器端函数,用于处理数据变更和其他操作。如果对您的路由发出了非 GET 请求(DELETEPATCHPOSTPUT),则将在 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,只调用一个操作

被调用的路由将是最深的匹配路由,除非最深的匹配路由是“索引路由”。在这种情况下,它将发布到索引的父路由(因为它们共享相同的 URL,父路由获胜)。

如果您想发布到索引路由,请在操作中使用 ?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">

另请参阅

文档和示例根据 MIT