React Router v7 已发布。 查看文档
未找到处理

未找到 (404) 处理

当在 Web 服务器上找不到文档时,它应该发送一个 404 状态码。 这会向机器指示该文档不存在:搜索引擎不会索引它,CDN 不会缓存它等等。如今,大多数 SPA 无论页面是否存在都将所有内容都作为 200 提供,但对于你来说,这种情况今天结束!

Remix 站点应发送 404 的主要情况有两种

  • URL 与应用程序中的任何路由都不匹配
  • 您的加载器未找到任何数据

第一种情况已由 Remix 处理,您不必自己抛出响应。它知道您的路由,因此它知道是否没有任何匹配项(考虑使用Splat 路由 来处理这种情况)。第二种情况取决于您,但这非常容易。

如何发送 404

一旦您知道您没有用户正在寻找的内容,您就应该抛出一个响应

export async function loader({
  params,
}: LoaderFunctionArgs) {
  const page = await db.page.findOne({
    where: { slug: params.slug },
  });

  if (!page) {
    throw new Response(null, {
      status: 404,
      statusText: "Not Found",
    });
  }

  return json(page);
}

Remix 将捕获该响应,并将您的应用程序发送到错误边界路径。这实际上与 Remix 的自动错误处理完全相同,但您将不会从 useRouteError() 接收到 Error,而是接收到一个包含响应 statusstatusText 和提取的 data 的对象。

抛出响应的好处在于,加载器中的代码会停止执行。您的其余代码不必处理页面是否定义的可能性(这对于 TypeScript 尤其方便)。

抛出还确保如果加载器不成功,则不会渲染您的路由组件。您的路由组件只需考虑“正常路径”。它们不需要挂起状态、错误状态或在此处的示例中,不需要未找到状态。

根错误边界

您可能已经在应用程序的根目录中有一个。 这将处理所有未在嵌套路由中处理的抛出响应。 这是一个示例

export function ErrorBoundary() {
  const error = useRouteError();
  return (
    <html>
      <head>
        <title>Oops!</title>
        <Meta />
        <Links />
      </head>
      <body>
        <h1>
          {isRouteErrorResponse(error)
            ? `${error.status} ${error.statusText}`
            : error instanceof Error
            ? error.message
            : "Unknown Error"}
        </h1>
        <Scripts />
      </body>
    </html>
  );
}
文档和示例在以下许可下授权 MIT