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
這些參數與傳遞給 createBrowserRouter
的 routes
/basename
相同
handler.query(request, opts)
handler.query()
方法會接受一個 Fetch 請求,執行路由比對,並根據請求執行所有相關的路由動作/載入器方法。傳回的 context
值包含所有必要的資訊來渲染請求的 HTML 文件(路由等級的 actionData
、loaderData
、errors
等)。如果任何比對的路由傳回或拋出重新導向回應,則 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()
區段中的範例。
另請參閱