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
这些与您传递给 createBrowserRouter
的 routes
/basename
相同。
handler.query(request, opts)
handler.query()
方法接收一个 Fetch 请求,执行路由匹配,并根据请求执行所有相关的路由操作/加载器方法。返回的 context
值包含渲染请求的 HTML 文档所需的所有信息(路由级别的 actionData
、loaderData
、errors
等)。如果任何匹配的路由返回或抛出重定向响应,则 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()
部分中的示例。
另请参阅