全书目录

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

九、`loader`:入港查验窗口,只读,不乱写

1 分钟 381 字 第 572 / 962 个阅读单元

loader 是 Remix 的灵魂之一。

它的职责非常纯:

为当前路由读取数据。

tsx
export async function loader({ params, request }: LoaderFunctionArgs) {
  const url = new URL(request.url);
  const status = url.searchParams.get("status");

  const ships = await listShips({ status });
  return json({ ships, status });
}

loader 的几个铁律:

#1. 它运行在服务端

至少在 Remix v2 的标准心智里,loader 是服务端逻辑。

你可以安全地:

  • 读数据库
  • 读私密环境变量
  • 查当前登录用户
  • 做权限校验

#2. 它返回的是“能跨网络传输的数据”

不要返回奇怪对象、方法、数据库实例。

正确心智是:

loader 返回的是要交给浏览器的货单,不是整个仓库。

#3. 不要手动调用 loader

这是新人非常常见的误区。

错的思路:

tsx
const data = loader(); // 不要这样

对的思路:

tsx
const data = useLoaderData<typeof loader>();

因为 loader 不是普通工具函数,它是 Remix 的请求生命周期钩子。

#4. 可以抛 Response

这很重要,因为 404、401、403 这类本来就是 Web 语义。

tsx
export async function loader({ params }: LoaderFunctionArgs) {
  const ship = await getShipById(params.shipId!);

  if (!ship) {
    throw new Response("未找到该船舶", { status: 404 });
  }

  return json({ ship });
}

这不是“异常写法”,而是很标准的港口规则:

查验不通过,就直接走错误航道。