API 参考
React Router 是React 组件、hooks和一套工具的集合,使使用React构建多页面应用程序变得容易。此参考包含 React Router 中各种接口的函数签名和返回类型。
概述
包
React Router 以三个不同的包发布到 npm:
react-router
包含 React Router 的大部分核心功能,包括路由匹配算法和大部分核心组件和hooksreact-router-dom
包含react-router
中的一切并增加了一些DOM专用的API,其中包括<BrowserRouter>
,<HashRouter>
,和<Link>
react-router-native
包含react-router
中的一切并增加了一些React Native专用的API,包括<NativeRouter>
和一个native版本的<Link>
当安装react-router-dom
或react-router-native
时,会自动包含react-router
作为依赖,并且它们都从react-router
暴露所有接口。当你import
它们的模块的时候,你应该总是从react-router-dom
或react-router-native
导入,绝对不要直接从react-router
导入. 否则,你可能会意外地在你的应用中导入不匹配的库版本。
如果你将React Router安装为全局(使用<script>
标签),你可以在window.ReactRouterDOM
对象上找到它。如果你从 npm 安装它,你可以通过import
来导入需要的模块。本参考中的示例均使用import
语法。
设置
为了让 React Router 在你的应用中工作,你需要在节点树的根节点或其边上渲染一个路由器节点。我们提供了几种不同的路由器,具体取决于你的应用程序运行的环境。
<BrowserRouter>
或<HashRouter>
应该在在 Web 浏览器中运行时使用(选择哪个取决于你喜欢或需要的 URL 样式)<StaticRouter>
应该在服务端渲染网站时使用<NativeRouter>
应该在React Native应用程序中使用<MemoryRouter>
在测试场景中很有用,并作为其他路由器的参考实现
这些路由器提供了 React Router 在特定环境中运行所需的上下文。如果出于某种原因需要更细粒度的控制,你也可以在每个渲染器都内置一个<Router>
组件。但是很可能你只需要其中一个内部的路由器。
路由
路由是决定哪些 React 元素将在你的应用程序的给定页面上渲染以及它们将如何嵌套的过程。React Router 提供了两个接口来定义你的路由。
- JSX中可以使用
<Routes>
和<Route>
来定义 - 如果你更喜欢配置式路由则可以使用
useRoutes
包内部使用的一些底层代码也公开为公共 API,以防你出于某种原因需要构建自己的高级接口
matchPath
- 根据 URL 路径名匹配路径模式matchRoutes
- 将一组路线与某个 location对象匹配createRoutesFromChildren
- 从一组 React 组件(例如<Route>
)创建路由配置
导航
React Router 的导航接口让你可以通过修改当前location对象来更改当前渲染的页面。有两个主要接口/ 组件 可用于在你的应用程序中的页面之间导航,根据你的需要来选择。
<Link>
和<NavLink>
渲染一个可访问的<a>
标签,而TouchableHighlight
则在 React Native 上渲染。这让用户可以通过单击或点击页面上的点击来启动导航。useNavigate
和<Navigate>
让你以编程方式进行导航,通常在事件处理程序中或用于响应某些状态变化
同样我们暴露内部的一些低级 API,它们在构建你自己的导航界面时也可能很有用。
useResolvedPath
- 解析当前location的相对路径useHref
- 解析合适的相对路径来作为<a href>
标签使用useLocation
和useNavigationType
- 这些描述了当前location以及我们如何到达那里useLinkClickHandler
- 当在react-router-dom
中构建一个自定义的<Link>
时返回一个用于导航的事件处理器useLinkPressHandler
- 当在react-router-native
中构建一个自定义的<Link>
时返回一个用于导航的事件处理器resolvePath
- 根据给定的 URL 路径名解析相对路径
搜索参数
Access to the URL search parameters is provided via the useSearchParams
hook.
通过提供的useSearchParams hook
hook来访问URL搜索参数。
参考
<BrowserRouter>
类型声明
declare function BrowserRouter(
props: BrowserRouterProps
): React.ReactElement;
interface BrowserRouterProps {
basename?: string;
children?: React.ReactNode;
window?: Window;
}
<BrowserRouter>
是在 Web 浏览器中运行 React Router 的推荐接口。<BrowserRouter>
组件使用干净的 URL 将当前位置存储在浏览器的地址栏中,并使用浏览器的内置历史堆栈进行导航。
<BrowserRouter window>
默认使用当前文档的defaultView
,但它也可用于跟踪对另一个窗口的 URL 的更改,例如在<iframe>
中。
import * as React from "react";
import * as ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
{/* The rest of your app goes here */}
</BrowserRouter>,
root
);
<HashRouter>
类型声明
declare function HashRouter(
props: HashRouterProps
): React.ReactElement;
interface HashRouterProps {
basename?: string;
children?: React.ReactNode;
window?: Window;
}
当 URL 由于某种原因不应(或不能)发送到服务器时,浏览器可以使用<HashRouter>
方案。在某些你无法完全控制服务器的共享托管方案中,可能会发生这种情况。在这些情况下,<HashRouter>
可以将当前位置存储在当前 URL的hash
部分中,因此永远不会将其发送到服务器。
<HashRouter window>
默认使用当前文档的defaultView
,但它也可用于跟踪对另一个窗口 URL 的更改,例如在<iframe>
中。
import * as React from "react";
import * as ReactDOM from "react-dom";
import { HashRouter } from "react-router-dom";
ReactDOM.render(
<HashRouter>
{/* The rest of your app goes here */}
</HashRouter>,
root
);
我们强烈不建议你使用
HashRouter
,除非不得不用
<NativeRouter>
类型声明
declare function NativeRouter(
props: NativeRouterProps
): React.ReactElement;
interface NativeRouterProps extends MemoryRouterProps {}
<NativeRouter>
是在React Native应用中运行 React Router 的推荐接口。
<NativeRouter initialEntries>
默认为["/"]
(根URL/
中的单个条目)<NativeRouter initialIndex>
默认为initialEntries
的最后一个索引
import * as React from "react";
import { NativeRouter } from "react-router-native";
function App() {
return (
<NativeRouter>
{/* The rest of your app goes here */}
</NativeRouter>
);
}
<MemoryRouter>
类型声明
declare function MemoryRouter(
props: MemoryRouterProps
): React.ReactElement;
interface MemoryRouterProps {
basename?: string;
children?: React.ReactNode;
initialEntries?: InitialEntry[];
initialIndex?: number;
}
<MemoryRouter>
将其位置存储在内存的一个数组中。与<BrowserHistory>
和<HashHistory>
不同,它不依赖于外部源,如浏览器中的历史堆栈。这使其非常适合需要完全控制历史堆栈的场景,例如测试。
<MemoryRouter initialEntries>
默认为["/"]
(根URL/
中的单个条目)<MemoryRouter initialIndex>
默认为initialEntries
的最后一个索引
提示:
大多数 React Router 的测试都是使用
<MemoryRouter>
作为事实来源编写的,因此你只需浏览我们的测试,就可以看到一些使用它的很好的例子 。
import * as React from "react";
import { create } from "react-test-renderer";
import {
MemoryRouter,
Routes,
Route
} from "react-router-dom";
describe("My app", () => {
it("renders correctly", () => {
let renderer = create(
<MemoryRouter initialEntries={["/users/mjackson"]}>
<Routes>
<Route path="users" element={<Users />}>
<Route path=":id" element={<UserProfile />} />
</Route>
</Routes>
</MemoryRouter>
);
expect(renderer.toJSON()).toMatchSnapshot();
});
});
<Link>
笔记:
这是网页版的
<Link>
。对于 React Native 版本, 请转到此处。
类型声明
declare function Link(props: LinkProps): React.ReactElement;
interface LinkProps
extends Omit<
React.AnchorHTMLAttributes<HTMLAnchorElement>,
"href"
> {
replace?: boolean;
state?: any;
to: To;
reloadDocument?: boolean;
}
type To = Partial<Location> | string;
<Link>
是允许用户通过点击它来导航到另一个页面组件。在 react-router-dom
中,一个<Link>
将渲染一个拥有指向资源的真实href
属性的可访问的<a>
标签。这意味着<Link>
会像你期望的那样单击工作。你可以使用<Link reloadDocument>
跳过客户端路由并让浏览器正常处理转换(就好像它是一个<a href>
)。
import * as React from "react";
import { Link } from "react-router-dom";
function UsersIndexPage({ users }) {
return (
<div>
<h1>Users</h1>
<ul>
{users.map(user => (
<li key={user.id}>
<Link to={user.id}>{user.name}</Link>
</li>
))}
</ul>
</div>
);
}
<Link to>
的相对路径值(不以 开头/
)会相对于父路由解析,这意味着它建立在渲染该<Link>
的父路径的URL的基础上. 它可能包含..
链接到层次结构更上一层的路由。在这些情况下,..
与命令行cd
功能完全一样;每个..
删除父路径的一段。
笔记:
带有
..
的<Link to>
的行为与正常的<a href>
不同,当 当前 URL 以/
结尾时<Link to>
会忽略尾部斜杠,并删除 每个..
对应的一个 URL 段。 但是<a href>
值处理..
, 当前 URL 以/
结尾与不以/
结尾的情况是不同的。
<Link>
(React Native)
笔记:
这是 React Native 版本的
<Link>
. 对于web版本, 请转到此处。
类型声明
declare function Link(props: LinkProps): React.ReactElement;
interface LinkProps extends TouchableHighlightProps {
children?: React.ReactNode;
onPress?(event: GestureResponderEvent): void;
replace?: boolean;
state?: State;
to: To;
}
<Link>
是一个许用户通过点击它来导航到另一个视图的组件,类似于<a>
标签在 Web 应用中的工作方式。在 中react-router-native
, <Link>
渲染一个TouchableHighlight
。要覆盖默认样式和行为,请参阅参考TouchableHighlight
的Props属性。
import * as React from "react";
import { View, Text } from "react-native";
import { Link } from "react-router-native";
function Home() {
return (
<View>
<Text>Welcome!</Text>
<Link to="/profile">Visit your profile</Link>
</View>
);
}
<NavLink>
类型声明
declare function NavLink(
props: NavLinkProps
): React.ReactElement;
interface NavLinkProps
extends Omit<LinkProps, "className" | "style"> {
caseSensitive?: boolean;
className?:
| string
| ((props: { isActive: boolean }) => string);
end?: boolean;
style?:
| React.CSSProperties
| ((props: {
isActive: boolean;
}) => React.CSSProperties);
}
<NavLink>
是一种特殊的 <Link>
,它知道自己是否是"active"状态。 这在构建导航菜单(例如面包屑或一组选项卡)时非常有用,你可以在其中显示当前选择了哪些选项卡。 它还为屏幕阅读器等辅助技术提供了有用的上下文。
默认情况下,当它处于激活状态时,一个 active
类被添加到一个 <NavLink>
组件中。 这为大多数从 v5 升级的用户提供了相同的简单样式机制。 与 v6.0.0-beta.3
的一个区别是 activeClassName
和 activeStyle
已从 NavLinkProps
中删除。 相反,你可以将函数传递给style
或className
,这将允许你根据组件的激活状态自定义内联样式或类字符串。
import * as React from "react";
import { NavLink } from "react-router-dom";
function NavList() {
// This styling will be applied to a <NavLink> when the
// route that it links to is currently selected.
let activeStyle = {
textDecoration: "underline"
};
return (
<nav>
<ul>
<li>
<NavLink
to="messages"
style={({ isActive }) =>
isActive ? activeStyle : undefined
}
>
Messages
</NavLink>
</li>
<li>
<NavLink
to="tasks"
style={({ isActive }) =>
isActive ? activeStyle : undefined
}
>
Tasks
</NavLink>
</li>
</ul>
</nav>
);
}
如果你更喜欢 v5 API,你可以创建自己<NavLink />
的包装组件:
import * as React from "react";
import { NavLink as BaseNavLink } from "react-router-dom";
const NavLink = React.forwardRef(
({ activeClassName, activeStyle, ...props }, ref) => {
return (
<BaseNavLink
ref={ref}
{...props}
className={({ isActive }) =>
[
props.className,
isActive ? activeClassName : null
]
.filter(Boolean)
.join(" ")
}
style={({ isActive }) => ({
...props.style,
...(isActive ? activeStyle : null)
})}
/>
);
}
);
如果使用了end
prop,它会确保当它的后代路径匹配时,这个组件不会被匹配为"激活"。例如,要显示仅在网站根目录而非任何其他 URL 中都处于激活状态的链接,你可以使用:
<NavLink to="/" end>
Home
</NavLink>
<Navigate>
类型声明
declare function Navigate(props: NavigateProps): null;
interface NavigateProps {
to: To;
replace?: boolean;
state?: State;
}