React 路由
2020-06-28 本文已影响0人
zaven
React Router是 react 官方推荐的一款路由库。实现单页面应用的利器。
本教程主要围绕V5.x版本来做相关介绍,其他版本可参考官方文档
React Router其实分为几个版本
- 绑定了 DOM 操作的 react-router-dom(常用于 web 应用)
- 用在 React Native 上的 react-router-native(用于 native App)
- react-router-config 路由的设置,可以实现类似vue中的路由守卫功能
安装 路由
npm install react-router-dom --save
简单的路由配置
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
function Index() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
return <h2>Users</h2>;
}
function AppRouter() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about/">About</Link>
</li>
<li>
<Link to="/users/">Users</Link>
</li>
</ul>
</nav>
<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" component={Users} />
</div>
</Router>
);
}
export default AppRouter;
从上述案例也可以看出,在react-route-dom
中,存在以下几个常用的对象
名称 | 作用 |
---|---|
BrowserRouter | 使用传统的url模式 |
HashRouter | 使用哈希路由的模式 |
Route | 用来装路由对应的内容 |
Link | 用来指定路由路径的 |
Swich | 只可以匹配到一个路由 |
Redirect | 路由重定向 |
exact | 精确匹配路由 |
match | 路由对象的一个存放路由参数的的属性 |
location | 路由对象的一个存放URL信息的属性 |
history | 路由对象的一个控制路由跳转的属性 |
component | 路由渲染的一种方式 |
render | 路由渲染的一种方式 |
children | 路由渲染的一种方式 |
案例1
- 导入路由必备对象
import { HashRouter as Router, Route, Link } from "react-router-dom";
- 定义不同路由的内容- (其实是个组件)
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
return <h2>Users</h2>;
}
- 使用路由
function AppRouter() {
return (
{/* 1 使用Router将Link 和 Route包含起来 */}
<Router>
<div className="route">
<nav>
<ul>
{/* 2 导航链接 */}
<li> <Link to="/">Home</Link> </li>
<li> <Link to="/about/">About</Link> </li>
<li> <Link to="/users/">Users</Link> </li>
</ul>
</nav>
<div className="content">
{/* 3 链接对应的内容 */}
<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" component={Users} />
</div>
</div>
</Router>
);
}
常见的路由标签和路由属性
React的路由默认匹配规则 类似:
if(link.indexOf("/")){
...
}
if(link.indexOf("/about/")){
...
}
当 在route
上加上 exact
属性后,变成
if( link === "/" ){
...
}
if( link === "/about/" ){
...
}
在 1 的基础上 不加 exact
加 Switch
后 变成了
<Switch>
{/* 链接对应的内容 */}
<Route path="/" component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" component={Users} />
</Switch>
它的原理类似:if-else if ...
if(link.indexOf("/")){
...
}
else if(link.indexOf("/about/")){
...
}
有时候,为了防止用户输入一个不存在的路由,我们会设置一个 404组件
function PageNotFound() {
return <h2>404啦</h2>
}
<Switch>
<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" component={Users} />
{/* 设置一个404页面 */}
<Route path="/404/" component={PageNotFound} />
</Switch>
因为,用户不可能自己输入一个 url:404,用户更多的是输入一些错乱的路径 dfasdfsdf等
因此,我们需要一个重定向 Redirect
import {Redirect } from "react-router-dom";
<Switch>
<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" component={Users} />
<Route path="/404/" component={PageNotFound} />
{/* 可以匹配到除以上的路由规则外的所有路由 */}
<Redirect to="/404/" ></Redirect>
</Switch>
渲染方式
在React的中,有3种渲染方式
- component 每次都会触发组件的对应的生命周期
- render 内联模式渲染 性能会更高 props需要传递到函数内
- children 会一直渲染 不管匹配模式
<Route path="/about/" component={About} />
<Route path="/about/" render={(props) => <About {...props} />}/>
<Route path="/about/" children={() => <About/>}/>
匹配参数
有时候我们需要在链接中和内容中传递参数
通过 route
标签的 path属性来指定参数
<Route path="/users/:id/" exact component={UserDetail} />
通过 props属性中的 history
对象来进行 逻辑跳转
const {id}=e.currentTarget.dataset;
props.history.push(`/users/${id}/`);
通过 props对象的match对象来获取参数
class UserDetail extends Component {
render() {
const { id } = this.props.match.params;
return <h1>{id}</h1>
}
}