待處理 UI
本頁面

待處理 UI

當使用者導航到新路由,或提交資料到動作時,UI 應立即以待處理或樂觀狀態回應使用者的動作。應用程式碼負責處理此行為。

全域待處理導航

當使用者導航到新網址時,會先等待下一頁的 loaders 完成,然後才渲染下一頁。您可以從 useNavigation 取得待處理狀態。

import { useNavigation } from "react-router";

export default function Root() {
  const navigation = useNavigation();
  const isNavigating = Boolean(navigation.location);

  return (
    <html>
      <body>
        {isNavigating && <GlobalSpinner />}
        <Outlet />
      </body>
    </html>
  );
}

區域待處理導航

待處理指示器也可以本地化到連結。NavLink 的 children、className 和 style props 可以是接收待處理狀態的函式。

import { NavLink } from "react-router";

function Navbar() {
  return (
    <nav>
      <NavLink to="/home">
        {({ isPending }) => (
          <span>Home {isPending && <Spinner />}</span>
        )}
      </NavLink>
      <NavLink
        to="/about"
        style={({ isPending }) => ({
          color: isPending ? "gray" : "black",
        })}
      >
        About
      </NavLink>
    </nav>
  );
}

待處理表單提交

當表單提交時,UI 應立即以待處理狀態回應使用者的動作。使用 fetcher 表單最容易做到這一點,因為它有自己的獨立狀態(而普通表單會導致全域導航)。

import { useFetcher } from "react-router";

function NewProjectForm() {
  const fetcher = useFetcher();

  return (
    <fetcher.Form method="post">
      <input type="text" name="title" />
      <button type="submit">
        {fetcher.state !== "idle"
          ? "Submitting..."
          : "Submit"}
      </button>
    </fetcher.Form>
  );
}

對於非 fetcher 表單提交,待處理狀態可在 useNavigation 上取得。

import { useNavigation, Form } from "react-router";

function NewProjectForm() {
  const navigation = useNavigation();

  return (
    <Form method="post" action="/projects/new">
      <input type="text" name="title" />
      <button type="submit">
        {navigation.formAction === "/projects/new"
          ? "Submitting..."
          : "Submit"}
      </button>
    </Form>
  );
}

樂觀 UI

當表單提交資料已知 UI 的未來狀態時,可以實作樂觀 UI 以獲得即時的使用者體驗。

function Task({ task }) {
  const fetcher = useFetcher();

  let isComplete = task.status === "complete";
  if (fetcher.formData) {
    isComplete = fetcher.formData.get("status");
  }

  return (
    <div>
      <div>{task.title}</div>
      <fetcher.Form method="post">
        <button
          name="status"
          value={isComplete ? "incomplete" : "complete"}
        >
          {isComplete ? "Mark Incomplete" : "Mark Complete"}
        </button>
      </fetcher.Form>
    </div>
  );
}

下一步:測試

文件和範例 CC 4.0