主分支
分支
主分支 (6.23.1)开发分支
版本
6.23.1v4/5.xv3.x
createStaticHandler
本页内容

createStaticHandler

createStaticHandler 用于在服务器(例如 Node 或其他 Javascript 运行时)上执行数据获取和提交,然后再通过 <StaticRouterProvider> 对您的应用程序进行服务器端渲染。有关更完整的概述,请参阅 服务器端渲染 指南。

import {
  createStaticHandler,
  createStaticRouter,
  StaticRouterProvider,
} from "react-router-dom/server";
import Root, {
  loader as rootLoader,
  ErrorBoundary as RootBoundary,
} from "./root";

const routes = [
  {
    path: "/",
    loader: rootLoader,
    Component: Root,
    ErrorBoundary: RootBoundary,
  },
];

export async function renderHtml(req) {
  let { query, dataRoutes } = createStaticHandler(routes);
  let fetchRequest = createFetchRequest(req);
  let context = await query(fetchRequest);

  // If we got a redirect response, short circuit and let our Express server
  // handle that directly
  if (context instanceof Response) {
    throw context;
  }

  let router = createStaticRouter(dataRoutes, context);
  return ReactDOMServer.renderToString(
    <React.StrictMode>
      <StaticRouterProvider
        router={router}
        context={context}
      />
    </React.StrictMode>
  );
}

类型声明

declare function createStaticHandler(
  routes: AgnosticRouteObject[],
  opts?: CreateStaticHandlerOptions
): StaticHandler;

interface CreateStaticHandlerOptions {
  basename?: string;
  future?: Partial<StaticHandlerFutureConfig>;
  mapRouteProperties?: MapRoutePropertiesFunction;
}

interface StaticHandlerFutureConfig {
  v7_relativeSplatPath: boolean;
  v7_throwAbortReason: boolean;
}

interface MapRoutePropertiesFunction {
  (route: AgnosticRouteObject): {
    hasErrorBoundary: boolean;
  } & Record<string, any>;
}

interface StaticHandler {
  dataRoutes: AgnosticDataRouteObject[];
  query(
    request: Request,
    opts?: {
      requestContext?: unknown;
    }
  ): Promise<StaticHandlerContext | Response>;
  queryRoute(
    request: Request,
    opts?: {
      routeId?: string;
      requestContext?: unknown;
    }
  ): Promise<any>;
}

routes/basename

这些与您传递给 createBrowserRouterroutes/basename 相同。

handler.query(request, opts)

handler.query() 方法接收一个 Fetch 请求,执行路由匹配,并根据请求执行所有相关的路由操作/加载器方法。返回的 context 值包含渲染请求的 HTML 文档所需的所有信息(路由级别的 actionDataloaderDataerrors 等)。如果任何匹配的路由返回或抛出重定向响应,则 query() 将以 Fetch Response 的形式返回该重定向。

如果请求被中止,query 将抛出错误,例如 Error("query() call aborted: GET /path")。如果您想抛出本机 AbortSignal.reason(默认情况下为 DOMException),您可以选择加入 future.v7_throwAbortReason 未来标志。DOMException 在 Node 17 中添加,因此您必须使用 Node 17 或更高版本才能使其正常工作。

opts.requestContext

如果您需要将信息从您的服务器传递到 Remix 操作/加载器,您可以使用 opts.requestContext,它将显示在您的操作/加载器中的上下文参数中。

const routes = [{
  path: '/',
  loader({ request, context }) {
    // Access `context.dataFormExpressMiddleware` here
  },
}];

export async function render(req: express.Request) {
  let { query, dataRoutes } = createStaticHandler(routes);
  let remixRequest = createFetchRequest(request);
  let staticHandlerContext = await query(remixRequest, {
    // Pass data from the express layer to the remix layer here
    requestContext: {
      dataFromExpressMiddleware: req.something
    }
 });
 ...
}

handler.queryRoute(request, opts)

handler.queryRoute 是一个更具针对性的版本,它查询单个路由并根据请求运行其加载器或操作。默认情况下,它将根据请求 URL 匹配目标路由。返回值是加载器或操作返回的值,通常是 Response 对象。

如果请求被中止,query 将抛出错误,例如 Error("queryRoute() call aborted: GET /path")。如果您想抛出本机 AbortSignal.reason(默认情况下为 DOMException),您可以选择加入 future.v7_throwAbortReason 未来标志。DOMException 在 Node 17 中添加,因此您必须使用 Node 17 或更高版本才能使其正常工作。

opts.routeId

如果您需要调用与 URL 不完全对应的特定路由操作/加载器(例如,父路由加载器),您可以指定 routeId

staticHandler.queryRoute(new Request("/parent/child"), {
  routeId: "parent",
});

opts.requestContext

如果您需要将信息从您的服务器传递到 Remix 操作/加载器,您可以使用 opts.requestContext,它将显示在您的操作/加载器中的上下文参数中。请参阅上面 query() 部分中的示例。

另请参阅