全书目录

第三十一篇:Remix 完全指南 —— Web 原生航运港宇宙

十四、Pending UI:港口大屏告诉你“正在靠港”

1 分钟 271 字 第 577 / 962 个阅读单元

Remix 很重视“网络感知 UI”。

因为 Web 不是本地内存操作,而是真正在走网络、走服务器、走数据库。

#页面级 pending:useNavigation

tsx
import { Outlet, useNavigation } from "@remix-run/react";

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

  return (
    <>
      {isNavigating && <div className="global-loading">船只靠港中...</div>}
      <Outlet />
    </>
  );
}

#局部 pending:fetcher.state

tsx
const fetcher = useFetcher();

<button type="submit" disabled={fetcher.state !== "idle"}>
  {fetcher.state === "submitting" ? "提交中..." : "提交"}
</button>

#Optimistic UI:先在屏幕上预演结果

tsx
function StatusToggle({ ship }: { ship: { id: string; status: string } }) {
  const fetcher = useFetcher();

  const optimisticStatus =
    fetcher.formData?.get("status")?.toString() ?? ship.status;

  return (
    <fetcher.Form method="post" action={`/ships/${ship.id}/status`}>
      <p>状态:{optimisticStatus}</p>
      <button name="status" value="arrived">切换为已到港</button>
      <button name="status" value="departed">切换为已离港</button>
    </fetcher.Form>
  );
}

Remix 的 pending UI 心智很成熟:

  • 不确定结果,就显示忙碌态
  • 结果可预测,就做 optimistic UI
  • 首屏关键数据先到,次要数据可 skeleton / defer

也就是说,Remix 并不是让你“隐藏网络”,而是让你诚实又顺滑地表达网络正在发生什么