4.1 react-router-dom4.0 基本介绍
4.1.1 HashRouter
与 BrowserRouter
- HashRouter:
http://localhost:3000/#/admin/buttons
- BrowserRouter:
http://localhost:3000/admin/buttons
4.1.2 Link
import {Link} from 'react-router-dom';
// 方式一
const Header = () => {
<header>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">about</Link></li>
<li><Link to="/three">three</Link></li>
</ul>
</nav>
</header>
}
// 方式二
<Link to={{ pathname: '/three/7' }}>Three #7</Link>
// 方式三 一个基本的location对象
{pathname: '/', search: '', hash: '', key: 'abc123' state: {}}
// props.match.params.number
定义:<Route path="/about/:number"/>
取值:this.props.match.params.number
4.1.3 Switch
正常4.0会匹配route下面所有路由,如果只想匹配其中一个
使用switch, 匹配其中一个,不再会继续往下匹配
<Switch>
<Route path='/admin/ui/buttons' component={Buttons} />
<Route path='/admin/ui/modals' component={Modals} />
<Route path='/admin/ui/loading' component={Loading} />
<Route path='/admin/ui/messages' component={Messages} />
<Route path='/admin/ui/tabs' component={Tabs} />
<Route path='/admin/ui/gallery' component={Gallery} />
<Route path='/admin/ui/carousel' component={Carousel} />
</Switch>
4.1.4 Redirect
重定向
<Redirect to="/admin/home"/>
4.2 路由demo演示
4.2.1 混合组件化
index => home => main/about/topics
// /index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Home from './pages/route-demo/route1/Home';
ReactDOM.render(<Home />, document.getElementById('root'));
serviceWorker.unregister();
// route-demo/home
import React, { Component } from 'react';
import {
HashRouter,
Route,
Link,
Switch
} from 'react-router-dom';
import Main from './main'
import About from './about'
import Topics from './topics'
class Home extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<HashRouter>
{/* HashRouter里面一定要有一个根节点,不能直接写Route */}
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">about</Link></li>
<li><Link to="/topics">topics</Link></li>
</ul>
<hr />
{/* exact 精准匹配 */}
<Route exact path="/" component={Main}></Route>
<Route path="/about" component={About}></Route>
<Route path="/topics" component={Topics}></Route>
</div>
</HashRouter>
);
}
}
export default Home;
4.2.2 路由配置化
- 路由配置化:把路由单独抽取出来,不和link写在一起
this.props.children
,他表示组件所有的子节点。index => router => home => admin/about/contact
// router.js
class IRouter extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<BrowserRouter>
<Home>
<Route exact path='/' component={Admin} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
</Home>
</BrowserRouter>
);
}
}
export default IRouter;
// home.js
class Home extends Component {
render() {
return (
<div>
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/about'>About Us</Link></li>
<li><Link to='/contact'>Contact Us</Link></li>
</ul>
<hr />
{this.props.children}
</div>
)
}
}
export default Home;
4.2.3 嵌套路由
- 一级路由
index => router => home => admin/about/contact
- 二级路由
admin => 介绍/文化/人才

// home.js
class Home extends Component {
render() {
return (
<div>
<ul>
<li><Link to='/admin'>Home</Link></li>
<li><Link to='/about'>About Us</Link></li>
<li><Link to='/contact'>Contact Us</Link></li>
</ul>
<hr />
{this.props.children}
</div>
)
}
}
export default Home;
//router.js
class IRouter extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<BrowserRouter>
<Home>
{/* 嵌套路由不用写component 写render 继续渲染下一级路由 */}
{/* 嵌套路由 不能加exact 否则不能匹配到`/admin` 只能精准匹配到`/` */}
<Route path='/admin' render={()=>
<Admin>
<Route path='/admin/company' component={About} />
<Route path='/admin/culture' component={About} />
<Route path='/admin/people' component={About} />
</Admin>
} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
</Home>
</BrowserRouter>
);
}
}
export default IRouter;
// admin.js
class Admin extends Component {
render() {
return (
<div>
This is Admin Page.
<ul>
<li><Link to='/admin/company'>公司介绍</Link></li>
<li><Link to='/admin/culture'>企业文化</Link></li>
<li><Link to='/admin/people'>广纳贤才</Link></li>
</ul>
<hr />
{this.props.children}
</div>
);
}
}
export default Admin;
4.2.4 react-router中的 this.props

this.props.history
包含了组件可以使用的各种路由系统的方法,常用的有 push 和 replace,两者都是跳转页面,但是 replace 不会引起页面的刷新,仅仅是改变 url。

this.props.location
相当于URL 的对象形式表示,通过 search 字段可以获取到 url 中的 query 信息。(这里 state 的含义与 HTML5 history.pushState API 中的 state 对象一样。每个 URL 都会对应一个 state 对象,你可以在对象里存储数据,但这个数据却不会出现在 URL 中。实际上,数据被存在了 sessionStorage 中)

this.props.match
React 获取 url 参数
包含了具体的 url 信息,在 params 字段中可以获取到各个路由参数的值。

//router.js
class IRouter extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<BrowserRouter>
<Home>
<Route path='/admin' render={()=>
<Admin>
{/* :id 可以通过this.props.match.params.id获取动态路由属性值 */}
<Route path='/admin/:id' component={Company} />
</Admin>
} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
</Home>
</BrowserRouter>
);
}
}
export default IRouter;
//company.js
class Company extends Component {
render() {
return (
<div>
动态路由的值: {this.props.match.params.id}
{console.log(this.props)}
</div>
)
}
}
export default Company;
4.2.5 404页面
<Route component={NoMatch} />
404页面不用加path=''
//home.js
class Home extends Component {
render() {
return (
<div>
<ul>
<li><Link to='/admin'>Home1</Link></li>
<li><Link to='/about'>About Us1</Link></li>
<li><Link to='/contact'>Contact Us1</Link></li>
<li><Link to='/product'>product</Link></li>
<li><Link to='/feedback'>feedback</Link></li>
</ul>
<hr />
{this.props.children}
</div>
)
}
}
export default Home;
//router.js
class IRouter extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<BrowserRouter>
<Home>
<Switch>
<Route path='/admin' render={() =>
<Admin>
{/* :id 可以通过this.props.match.params.id获取动态路由属性值 */}
<Route path='/admin/:id' component={Company}></Route>
</Admin>
} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
<Route component={NoMatch} />
<Route component={NoMatch} />
</Switch>
</Home>
</BrowserRouter>
);
}
}
export default IRouter;
//nomatch.js
class Main extends Component {
render() {
return (
<div>
404 not found
</div>
);
}
}
export default Main;