数据修改通过路由对象上的 action
属性定义的路由 actions 完成。当 action 完成后,页面上的所有 loader 数据都会被重新验证,从而使您的 UI 与数据保持同步,无需编写任何额外代码。
import { createBrowserRouter } from "react-router";
import { someApi } from "./api";
let router = createBrowserRouter([
{
path: "/projects/:projectId",
Component: Project,
action: async ({ request }) => {
let formData = await request.formData();
let title = formData.get("title");
let project = await someApi.updateProject({ title });
return project;
},
},
]);
Actions 可以通过 <Form>
声明式地调用,也可以通过 useSubmit
(或 <fetcher.Form>
和 fetcher.submit
)命令式地调用,通过引用路由的路径和 "post" 方法。
import { Form } from "react-router";
function SomeComponent() {
return (
<Form action="/projects/123" method="post">
<input type="text" name="title" />
<button type="submit">Submit</button>
</Form>
);
}
这会导致导航,并在浏览器历史记录中添加一个新条目。
您可以使用 useSubmit
命令式地向 action 提交表单数据。
import { useCallback } from "react";
import { useSubmit } from "react-router";
import { useFakeTimer } from "fake-lib";
function useQuizTimer() {
let submit = useSubmit();
let cb = useCallback(() => {
submit(
{ quizTimedOut: true },
{ action: "/end-quiz", method: "post" }
);
}, []);
let tenMinutes = 10 * 60 * 1000;
useFakeTimer(tenMinutes, cb);
}
这会导致导航,并在浏览器历史记录中添加一个新条目。
Fetchers 允许您在不引起导航(不在浏览器历史记录中添加新条目)的情况下向 actions(和 loaders)提交数据。
import { useFetcher } from "react-router";
function Task() {
let fetcher = useFetcher();
let busy = fetcher.state !== "idle";
return (
<fetcher.Form method="post" action="/update-task/123">
<input type="text" name="title" />
<button type="submit">
{busy ? "Saving..." : "Save"}
</button>
</fetcher.Form>
);
}
它们还具有命令式的 submit
方法。
fetcher.submit(
{ title: "New Title" },
{ action: "/update-task/123", method: "post" }
);
有关更多信息,请参阅使用 Fetcher指南。
Action 可以返回数据,这些数据可在路由组件中使用 useActionData
或在使用 fetcher 时通过 fetcher.data
访问。
function Project() {
let actionData = useActionData();
return (
<div>
<h1>Project</h1>
<Form method="post">
<input type="text" name="title" />
<button type="submit">Submit</button>
</Form>
{actionData ? (
<p>{actionData.title} updated</p>
) : null}
</div>
);
}
下一篇:导航