主機
分支
主機 (6.23.1)開發版
版本
6.23.1v4/5.xv3.x
createStaticHandler
本頁面

createStaticHandler

createStaticHandler 用於在透過 <StaticRouterProvider> 執行伺服器端渲染應用程式之前,在伺服器端(例如 Node 或其他 JavaScript 執行環境)進行資料提取和提交。如需更完整的概觀,請參閱 伺服器端渲染 指南。

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() 呼叫已中斷:GET /path")。如果您想擲出原生 AbortSignal.reason (預設為 DOMException),您可以選擇加入 future.v7_throwAbortReason 未來 flag。DOMException 已新增至 Node 17,因此您必須使用 Node 17 或更高版本才能正確運作。

opts.requestContext

如果您需要將資訊從您的伺服器傳遞到 Remix 動作/載入器,您可以使用 opts.requestContext 執行此操作,而且它會在 context 參數中出現在您的動作/載入器中。

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() 呼叫已中斷:GET /path")。如果您想擲出原生 AbortSignal.reason (預設為 DOMException),您可以選擇加入 future.v7_throwAbortReason 未來 flag。DOMException 已新增至 Node 17,因此您必須使用 Node 17 或更高版本才能正確運作。

opts.routeId

如果您需要呼叫與 URL 不完全對應的特定路由動作/載入器 (例如,父路由載入器),您可以指定一個 routeId

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

opts.requestContext

如果您需要將資訊從您的伺服器傳遞到 Remix 動作/載入器,您可以使用 opts.requestContext 執行此操作,而且它會在 context 參數中出現在您的動作/載入器中。請參閱上方 query() 區段中的範例。

另請參閱