action

action

关注 📼 Remix Singles: Data Mutations with Form + actionMultiple Forms and Single Button Mutations

路由 action 是一个仅用于服务器的函数,用于处理数据变更和其他操作。如果向你的路由(DELETEPATCHPOSTPUT)发出非 GET 请求,则该操作会在 loader 之前调用。

¥A route action is a server-only function to handle data mutations and other actions. If a non-GET request is made to your route (DELETE, PATCH, POST, or PUT) then the action is called before the loaders.

actionloader 具有相同的 API,唯一的区别在于调用方式。这使你可以将数据集的所有内容共置在一个路由模块中:读取数据、渲染数据的组件以及写入数据:

¥actions have the same API as loaders, the only difference is when they are called. This enables you to co-locate everything about a data set in a single route module: the data read, the component that renders the data, and the data writes:

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 匹配。与加载器 GET 不同,加载器会调用所有 GET 来构建 UI,而 ESM 只会调用一个操作。

¥When a POST is made to a URL, multiple routes in your route hierarchy will match the URL. Unlike a GET to loaders, where all of them are called to build the UI, only one action is called.

被调用的路由将是匹配最深层的路由,除非匹配最深层的路由是 "index route"。在这种情况下,它将发送到索引的父路由(因为它们共享相同的 URL,因此父路由优先)。

如果你想发布到索引路由,请在操作中使用 ?index<Form action="/accounts?index" method="post" />

¥If you want to post to an index route use ?index in the action: <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">

¥Also note that forms without an action prop (<Form method="post">) will automatically post to the same route within which they are rendered, so using the ?index param to disambiguate between parent and index routes is only useful if you're posting to an index route from somewhere besides the index route itself. If you're posting from the index route to itself, or from the parent route to itself, you don't need to define a <Form action> at all, omit it: <Form method="post">.

另请参阅:

¥See also:

Remix v2.17 中文网 - 粤ICP备13048890号