react-router-dom V5 使用指南(1)
- react-router 提供了路由核心接口,如 Router、Route、Switch 等,未提供终端操作相关的接口;
- react-router-dom 提供了浏览器端接口,BrowserRouter、HashRouter,Route、Link 等API;
- react-router-native 提供了 native 端的相关接口。
学习方法
初学者建议先熟悉一遍 官网文档react-router-dom,看找一篇阐述的比较清楚的实战文章,这里我整理了一些资料:
实用例子
路由跳转
演示地址:https://reactrouter.com/web/example/basic
,这是一个非常简单的例子,从这个例子可以学到在React中路由功能是如何实现的,没有什么难度:
- Link:实现了URL点击跳转的功能,点击它可以跳转到指定的路由URL
- Route:用于配置路由
- Switch:保证在一组路由中只渲染一个
获取 URL Params
演示地址:https://reactrouter.com/web/example/url-params
,这个例子也比较简单没什么值得说的:
- useParams: 可以在任意级别的组件里获取 URL Params。V5.1之前非Route子组件是没办法获取到,你需要借助 withRouter。
路由嵌套
演示地址:https://reactrouter.com/web/example/nesting
,路由嵌套理解为:在 Route 组件的子孙组件中存在 Route 组件,比如:
<Route path="/topics">
<h1>parent</h1>
<Route path="/topics/:topicId">
child
</Route>
</Route>
值得注意的是,演示地址中使用了 useRouteMatch
,它在这个例子中的作用是将与他匹配成功的路由信息找出来,举个例子就很容易理解:
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
useRouteMatch
} from "react-router-dom";
export default function NestingExample() {
return (
<Router>
<Switch>
<Route path="/topics">
<Topics />
</Route>
</Switch>
</Router>
);
}
function Topics() {
let { path, url } = useRouteMatch();
console.log(useRouteMatch())
// 在这里必须使用 useRouteMatch 找出当前匹配成功的 Route 的 path 信息, 否则子路由无法跳转
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${url}/rendering`}>Rendering with React</Link>
</li>
</ul>
<Switch>
<Route path={`${path}/:topicId`}>
<Topic />
</Route>
</Switch>
</div>
);
}
function Topic() {
let { topicId } = useParams();
console.log(useRouteMatch())
return (
<div>
<h3>{topicId}</h3>
</div>
);
}
当访问 url path 为 /topics/props-v-state
时,打印信息如下:
重定向
演示地址:https://reactrouter.com/web/example/auth-workflow
,重定向是路由系统中不可或缺的功能,常被用于登录跳转等场景中,由于React崇尚一切皆组件的思想,所以在React中,当您需要重定向时,只需返回一个 Redirect
组件:
// state 常用来携带额外信息
<Redirect
to={{
pathname: "/login",
state: { from: '/orders' }
}}
/>
在该演示地址代码中(简化后),一个非常值得学习的技巧是:ProtectedPage
是需要登录才能访问的,但是我们将登录校验以及重定向的操作封装到了 PrivateRoute
组件中,两者被隔离开,降低代码逻辑的耦合行,大大增大了代码的复用性:
export default function AuthExample() {
return (
<Router>
<div>
<Switch>
<Route path="/login">
<LoginPage />
</Route>
<PrivateRoute path="/protected">
<ProtectedPage />
</PrivateRoute>
</Switch>
</div>
</Router>
);
}
function PrivateRoute({ children, ...rest }) {
return (
<Route
{...rest}
render={({ location }) =>
fakeAuth.isAuthenticated ? (
children
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location }
}}
/>
)
}
/>
);
}