React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。
不使用react-router时的路由跳转方案:
import React from 'react';
// 引入页面
import Index from './pages/Index'; // 首页
import Article from './pages/Article'; // 文章页
import About from './pages/About'; // 关于页
class App extends React.Component {
constructor() {
super();
this.state = {
path: ''
}
}
componentDidMount() { // 生命周期:加载完毕
window.addEventListener('hashchange',()=>{ // 监听url锚点(#)变化
this.setState({
path: window.location.hash.substr(1)
})
})
}
render() {
let child;
switch (this.state.path) {
case '':
child = <Index></Index>
break;
case 'article':
child = <Article></Article>
break;
case 'about':
child = <About></About>
break;
default:
child = <Index></Index>
}
return (
<div>
<a href="#">首页</a>
<a href="#article"> | 文章页</a>
<a href="#about"> | 关于</a>
{child}
</div>
)
}
}
export default App;
这种方式面对页面简单,数量少的还能接受,程序大了之后,便难于维护与编写。
使用react-router:
1、安装
当前案例使用的版本为:
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1"
}
局部安装 react-router-dom
npm install react-router-dom -s
2、介绍react-router-dom中的几个主要组件和方法:
BrowderRouter:组件:用常规的URL路径。这些通常是外观最好的URL,但是它们要求正确配置服务器。具体来说,您的Web服务器需要在所有由React Router客户端管理的URL上提供相同的页面。
HashRouter: 组件:将当前位置存储在URL的hash一部分中,因此URL看起来像http://example.com/#/your/page
。由于哈希从不发送到服务器,因此这意味着不需要特殊的服务器配置。
Switch:组件:常常会用来包裹Route,它里面不能放其他元素,用来只显示一个路由。Switch用于匹配查找path,以匹配显示Route中的组件。
Route:组件:被包裹在Switch里面,放置被path匹配时显示的组件,被Switch查找。
Link:导航组件:提供超链接控制路由跳转,to属性可以是一个字符串(单纯path路径,也可以是一个对象)
// to对象属性
pathname: 路由字符串
search: 路由查找参数,如:?test=1
hash: 锚点字符串,会添加到路由尾部,如:#test
state: 额外参数,可以是一个对象,如:{name: 'test'}
NavLink:导航组件:是Link的特殊版本,他可以有更多的功能,可以设置更多的属性。
activeClassName(string):设置选中样式,默认值为active
activeStyle(object):当元素被选中时,为此元素添加样式
exact(bool):为true时,只有当导致和完全匹配class和style才会应用
strict(bool):为true时,在确定为位置是否与当前URL匹配时,将考虑位置pathname后的斜线
isActive(func)判断链接是否激活的额外逻辑的功能
Redirect:组件:当有没有匹配到任何路由时,重定向到指定路径,一般放在Switch里的最底部。
<Redirect to="/"></Redirect>
useRouteMatch:方法:获取组件匹配的路由对象。
isExact:是否严格模式
params:访问当前组件的路由携带参数
path:访问当前组件的路由匹配规则
url:访问当前组件的实际匹配的路由(实际显示的路由)
useParams:访问当前组件的路由携带参数,即 useRouteMatch 中的params。
更多更标准的解释可查看: 官方文档API
3、开始使用
示例:
import React from 'react';
import './App.css';
// 其中BrowserRouter 引入后改为别名Router,改别名的原因是为了易维护,不与使用HashRouter时发生冲突,而需要在此修改
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom';
// 引入页面
import Index from './pages/Index'; // 首页
import Article from './pages/Article'; // 文章页
import About from './pages/About'; // 关于页
class App extends React.Component {
render() {
return (
<div>
<Router>
<Link to="/">首页</Link>
<Link to="/article">文章页</Link>
<Link to="/about">关于页</Link>
<Switch>
<Route path="/about"> {/*路由匹配时将会渲染其中的组件*/}
<About />
</Route>
<Route path="/article"> {/*如果只是显示组件,可以这样写:<Route path="/article" component={Article} />*/}
<Article />
</Route>
<Route path="/">
<Index />
</Route>
</Switch>
</Router>
</div>
)
}
}
export default App;
4、嵌套路由
以上一个示例中的Article组件修改为例:
示例包含次级路由访问、动态路由访问。注意:在JSX中注释需要 {/**/} 包裹
import React from 'react'
import { useRouteMatch, useParams, Link, Route, Switch} from 'react-router-dom'
function Page(){
let match = useRouteMatch(); // 获取当前组件匹配的路由
return (
<div>
<h1>这是文章页</h1>
<Link to={`${match.url}/hot`}>最热文章</Link> {/*查看最热文章*/}
<Link to={`${match.url}/latest`}> | 最新文章</Link> {/*查看最热文章*/}
<Link to={`${match.url}/1`}> | 文章1</Link> {/* 查看id为1的文章*/}
<Link to={`${match.url}/2`}> | 文章2</Link> {/*查看id为2的文章*/}
<Switch>
<Route path={`${match.path}/hot`}> {/*匹配最热文章*/}
<h2>这是最热文章</h2>
</Route>
<Route path={`${match.path}/latest`}> {/*匹配最新文章*/}
<h2>这是最新文章</h2>
</Route>
<Route path={`${match.path}/:id`}> {/*匹配动态id查看文章,匹配文章id详情组件*/}
<ArticleDetail></ArticleDetail>
</Route>
</Switch>
</div>
)
}
function ArticleDetail() {
let { id } = useParams(); // 获取参数id
return (
<h1>这是文章{id}</h1>
)
}
export default Page;
官方英文文档:https://reacttraining.com/react-router/web/guides/quick-start
注:个人笔记,不作标准答案,仅供参考,不喜勿喷。