操作
本頁面內容

操作

資料變更透過路由操作完成。當操作完成時,頁面上所有的 loader 資料都會重新驗證,以保持 UI 與資料同步,無需編寫任何程式碼。

使用 action 定義的路由操作僅在伺服器上呼叫,而使用 clientAction 定義的操作則在瀏覽器中執行。

客戶端操作

客戶端操作僅在瀏覽器中執行,並且在同時定義客戶端和伺服器端操作時,優先於伺服器端操作。

// route('/projects/:projectId', './project.tsx')
import type { Route } from "./+types/project";
import { Form } from "react-router";
import { someApi } from "./api";

export async function clientAction({
  request,
}: Route.ClientActionArgs) {
  let formData = await request.formData();
  let title = formData.get("title");
  let project = await someApi.updateProject({ title });
  return project;
}

export default function Project({
  actionData,
}: Route.ComponentProps) {
  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>
  );
}

伺服器端操作

伺服器端操作僅在伺服器上執行,並從客戶端套件中移除。

// route('/projects/:projectId', './project.tsx')
import type { Route } from "./+types/project";
import { Form } from "react-router";
import { fakeDb } from "../db";

export async function action({
  request,
}: Route.ActionArgs) {
  let formData = await request.formData();
  let title = formData.get("title");
  let project = await fakeDb.updateProject({ title });
  return project;
}

export default function Project({
  actionData,
}: Route.ComponentProps) {
  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>
  );
}

呼叫操作

操作可以透過 <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 呼叫操作

您可以使用 useSubmit 以命令式方式將表單資料提交到操作。

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);
}

這將會導致導航,並在瀏覽器歷史記錄中新增一個新條目。

使用 fetcher 呼叫操作

Fetchers 允許您將資料提交到操作 (和 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" }
);

請參閱〈使用 Fetchers〉指南以取得更多資訊。


下一步:導航

文件和範例 CC 4.0