本页还没有译文
本页 56 段还没译成简体中文,下面显示的是英文原文。createBrowserRouter
还没翻译译自英文(reactrouter.com)本页 56 段都还没译
createBrowserRouter
Data
Summary
Create a new data router that manages the application
path via history.pushState
and history.replaceState.
Data Routers should not be held in React state. You should create your router
once outside of the React tree and pass it to <RouterProvider>.
You can use patchRoutesOnNavigation to add additional routes programmatically.
Signature
function createBrowserRouter(
routes: RouteObject[],
opts?: DOMRouterOpts,
): DataRouterParams
routes
Application routes
opts.basename
Basename path for the application.
opts.dataStrategy
Override the default data strategy of running loaders in parallel - see the docs for more information.
let router = createBrowserRouter(routes, {
async dataStrategy({
matches,
request,
runClientMiddleware,
}) {
const matchesToLoad = matches.filter((m) =>
m.shouldCallHandler(),
);
const results: Record<string, DataStrategyResult> = {};
await runClientMiddleware(() =>
Promise.all(
matchesToLoad.map(async (match) => {
results[match.route.id] = await match.resolve();
}),
),
);
return results;
},
});opts.future
Future flags to enable for the router.
opts.getContext
A function that returns an RouterContextProvider instance
which is provided as the context argument to client actions,
loaders and middleware.
This function is called to generate a fresh context instance on each
navigation or fetcher call.
import {
createContext,
RouterContextProvider,
} from "react-router";
const apiClientContext = createContext<APIClient>();
function createBrowserRouter(routes, {
getContext() {
let context = new RouterContextProvider();
context.set(apiClientContext, getApiClient());
return context;
}
})opts.hydrationData
When Server-Rendering and opting-out of automatic hydration, the
hydrationData option allows you to pass in hydration data from your
server-render. This will almost always be a subset of data from the
StaticHandlerContext value you get back from the StaticHandler's
query method:
const router = createBrowserRouter(routes, {
hydrationData: {
loaderData: {
// [routeId]: serverLoaderData
},
// may also include `errors` and/or `actionData`
},
});Partial Hydration Data
You will almost always include a complete set of loaderData to hydrate a
server-rendered app. But in advanced use-cases (such as Framework Mode's
clientLoader), you may
want to include loaderData for only some routes that were loaded/rendered
on the server. This allows you to hydrate some of the routes (such as the
app layout/shell) while showing a HydrateFallback component and running
the loaders for other routes
during hydration.
A route loader will run during
hydration in two scenarios:
- No hydration data is provided
In these cases the
HydrateFallbackcomponent will render on initial hydration - The
loader.hydrateproperty is set totrueThis allows you to run theloadereven if you did not render a fallback on initial hydration (i.e., to prime a cache with hydration data)
const router = createBrowserRouter(
[
{
id: "root",
loader: rootLoader,
Component: Root,
children: [
{
id: "index",
loader: indexLoader,
HydrateFallback: IndexSkeleton,
Component: Index,
},
],
},
],
{
hydrationData: {
loaderData: {
root: "ROOT DATA",
// No index data provided
},
},
}
);opts.instrumentations
Array of instrumentation objects allowing you to instrument the router and
individual routes prior to router initialization (and on any subsequently
added routes via route.lazy or patchRoutesOnNavigation). This is
mostly useful for observability such as wrapping navigations, fetches,
as well as route loaders/actions/middlewares with logging and/or performance
tracing. See the docs for more information.
let router = createBrowserRouter(routes, {
instrumentations: [logging]
});
let logging = {
router({ instrument }) {
instrument({
navigate: (impl, info) => logExecution(`navigate ${info.to}`, impl),
fetch: (impl, info) => logExecution(`fetch ${info.to}`, impl)
});
},
route({ instrument, id }) {
instrument({
middleware: (impl, info) => logExecution(
`middleware ${info.request.url} (route ${id})`,
impl
),
loader: (impl, info) => logExecution(
`loader ${info.request.url} (route ${id})`,
impl
),
action: (impl, info) => logExecution(
`action ${info.request.url} (route ${id})`,
impl
),
})
}
};
async function logExecution(label: string, impl: () => Promise<void>) {
let start = performance.now();
console.log(`start ${label}`);
await impl();
let duration = Math.round(performance.now() - start);
console.log(`end ${label} (${duration}ms)`);
}opts.patchRoutesOnNavigation
Lazily define portions of the route tree on navigations.
See PatchRoutesOnNavigationFunction.
By default, React Router wants you to provide a full route tree up front via
createBrowserRouter(routes). This allows React Router to perform synchronous
route matching, execute loaders, and then render route components in the most
optimistic manner without introducing waterfalls. The tradeoff is that your
initial JS bundle is larger by definition — which may slow down application
start-up times as your application grows.
To combat this, we introduced route.lazy
in v6.9.0
which lets you lazily load the route implementation (loader,
Component, etc.) while still
providing the route definition aspects up front (path, index, etc.).
This is a good middle ground. React Router still knows about your route
definitions (the lightweight part) up front and can perform synchronous
route matching, but then delay loading any of the route implementation
aspects (the heavier part) until the route is actually navigated to.
In some cases, even this doesn't go far enough. For huge applications, providing all route definitions up front can be prohibitively expensive. Additionally, it might not even be possible to provide all route definitions up front in certain Micro-Frontend or Module-Federation architectures.
This is where patchRoutesOnNavigation comes in (RFC).
This API is for advanced use-cases where you are unable to provide the full
route tree up-front and need a way to lazily "discover" portions of the route
tree at runtime. This feature is often referred to as "Fog of War",
because similar to how video games expand the "world" as you move around -
the router would be expanding its routing tree as the user navigated around
the app - but would only ever end up loading portions of the tree that the
user visited.
patchRoutesOnNavigation will be called anytime React Router is unable to
match a path. The arguments include the path, any partial matches,
and a patch function you can call to patch new routes into the tree at a
specific location. This method is executed during the loading portion of
the navigation for GET requests and during the submitting portion of
the navigation for non-GET requests.
opts.window
Window object
override. Defaults to the global window instance.
Returns
An initialized data router to pass to <RouterProvider>