虽然我们的应用程序只使用一个路由器,但是你可以根据自己的爱好选择一款路由使用。在 v6.4 中,引入了支持新数据API的新路由:
建议使用 v6.4 中引入的新路由来创建你的应用程序路由。
以下路由不支持数据API:
一、createBrowserRouter
这是所有 React Router Web 项目的推荐路由器,它使用 DOM History API来更新URL和管理历史堆栈。
它还支持 v6.4 数据api,如loaders
、actions
、fetchers
等。
import {createBrowserRouter} from "react-router-dom";
const router = createBrowserRouter([
{
path: '/login',
element: <div>登录</div>
},
{
path: '/',
element: <Layout/>,
children: [{
path: 'team',
element: <Team/>,
loader: teamLoader
}]
}
])
ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
.render(<RouterProvider router={router}/>)
类型声明
function createBrowserRouter(
routes: RouteObject[],
opts?: {
basename?: string;
feture?: FutureConfig;
hydrationData?: HydrationState;
window?: Window;
}
): RemixRouter;
basename:应用程序的根路径,适用于部署到指定子目录的情况。例如,你的网站根是放在www目录下,而你希望将 web 应用放在www/app
目录下,就可以将basename设置为如下:
createBrowserRouter(routes, {
basename: "/app"
})
basename 属性尾部的/
会被保留下来。
createBrowserRouter(routes, {
basename: "/app"
})
<Link to="/"/> // <a href="/app/">
createBrowserRouter(routes, {
basename: "/app/"
})
<Link to="/" /> // <a href="/app/">
routes
在 children 属性上嵌套路由的 Route 对象数组。
createBrowserRouter([
{
path: '/',
element: <Layout/>,
children: [{
path: 'team',
element: <Team/>,
loader: teamLoader
}]
}
])
二、createHashRouter
createHashRouter 和 createHistoryRouter 的功能相似。它不会使用普通的 URL,而是使用 URL 的散列来管理应用程序的URL。
createHashRouter([
{
path: '/',
element: <Layout/>,
children: [{
path: 'team',
element: <Team/>,
loader: teamLoader
}]
}
])
三、createMemoryRouter
内存路由器不使用浏览器历史,而是在内存中管理它自己的历史堆栈。主要用于测试和组件开发,如StoryBook,但也可以用在任何非浏览器环境中运行React Router。
import {
RouterProvider,
createMemoryRouter,
} from "react-router-dom";
import * as React from "react";
import {
render,
waitFor,
screen,
} from "@testing-library/react";
import "@testing-library/jest-dom";
import CalendarEvent from "./routes/event";
test("event route", async () => {
const FAKE_EVENT = { name: "test event" };
const routes = [
{
path: "/events/:id",
element: <CalendarEvent />,
loader: () => FAKE_EVENT,
},
];
const router = createMemoryRouter(routes, {
initialEntries: ["/", "/events/123"],
initialIndex: 1,
});
render(<RouterProvider router={router} />);
await waitFor(() => screen.getByRole("heading"));
expect(screen.getByRole("heading")).toHaveTextContent(
FAKE_EVENT.name
);
});
类型声明
function createMemoryRouter(
routes: RouteObject[],
opts?: {
basename?: string;
initialEntries?: InitialEntry[];
initialIndex?: number;
window?: Window;
}
): RemixRouter
initialEntries
历史堆栈中的初始条目,这允许你在历史堆栈中已有多个位置的情况下启动测试。
createMemoryRouter(routes, {
initialEntries: ['/', '/events/123']
})
initialIndex
要呈现的历史堆栈中的初始索引。这允许你在特定条目处开始测试。
createMemoryRouter(routes, {
initialEntries: ["/", "/events/123"],
initialIndex: 1, // start at "/events/123"
})
六、RouterProvider
给创建的router
提供一个渲染视图的容器,所有的路由对象都要传递给此组件以呈现你的应用程序视图并启用其余API,以便在component
中使用。
import { createBrowserRouter } from "react-router-dom"
const router = createBrowserRouter([
{
path: "/",
element: <Root/>,
children: [
{
path: "dashboard",
element: <Dashboard/>
}
]
}
])
ReactDOM.createRoot(document.getElementById("root")).render(
<RouterProvider
router={router}
fallbackElement={<BigSpinner/>}
/>
);
如果你的应用程序不是服务端渲染,BrowserRouter 将在挂载时启动所有匹配的路由加载器。在此期间,你可以提供一个fallbackElement
,向用户提供应用程序正在工作的一些提示。例如展示一个loading
动画。