1.路由的基本使用
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Home extends React.Component {
render() {
return (
<div>
home
</div>
)
}
}
class About extends React.Component {
render() {
return (
<div>
about
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom'
}
render() {
let {
msg } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
{
}
<Link to="/home">home</Link>
<Link to="/about">about</Link>
<Switch>
{
}
<Route path='/home' component={
Home}></Route>
<Route path='/about' component={
About}></Route>
</Switch>
</div>
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
2.NavLink的使用
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Home extends React.Component {
render() {
return (
<div>
home
</div>
)
}
}
class About extends React.Component {
render() {
return (
<div>
about
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom'
}
render() {
let {
msg } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
{
}
<NavLink to="/home" activeClassName='active'>home</NavLink>
<NavLink to="/about" activeClassName='active'>about</NavLink>
<Switch>
<Route path='/home' component={
Home}></Route>
<Route path='/about' component={
About}></Route>
</Switch>
</div>
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
3.Switch的使用
- 通常状态下
path
和component
是一一对应关系
- Switch可以提高路由的匹配效率(单一匹配)
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Home extends React.Component {
render() {
return (
<div>
home
</div>
)
}
}
class About extends React.Component {
render() {
return (
<div>
about
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom'
}
render() {
let {
msg } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
<NavLink to="/home" activeClassName='active996'>home</NavLink>
<NavLink to="/about" activeClassName='active996'>about</NavLink>
{
}
<Switch>
<Route path='/home' component={
Home}></Route>
<Route path='/about' component={
About}></Route>
<Route path='/about' component={
Home}></Route>
</Switch>
</div>
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
4.Redirect 的使用
- 一般写在所有路由组件的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Home extends React.Component {
render() {
return (
<div>
home
</div>
)
}
}
class About extends React.Component {
render() {
return (
<div>
about
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom'
}
render() {
let {
msg } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
<NavLink to="/home" activeClassName='active996'>home</NavLink>
<NavLink to="/about" activeClassName='active996'>about</NavLink>
<Switch>
<Route path='/home' component={
Home}></Route>
<Route path='/about' component={
About}></Route>
{
}
<Redirect to='/about'></Redirect>
</Switch>
</div>
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
5.push和replace(默认)属性的使用
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Home extends React.Component {
render() {
return (
<div>
home
</div>
)
}
}
class About extends React.Component {
render() {
return (
<div>
about
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom'
}
render() {
let {
msg } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
{
}
{
}
<NavLink to="/home" replace activeClassName='active996'>home</NavLink>
<NavLink to="/about" replace activeClassName='active996'>about</NavLink>
<Switch>
<Route path='/home' component={
Home}></Route>
<Route path='/about' component={
About}></Route>
</Switch>
</div>
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
6.路由的模糊匹配(默认)和严格匹配
- 默认使用的是模糊匹配(简单记:[输入的路径]必须包含要[匹配的路径],且顺序要一致)
- 开启严格匹配:
<Route exact={true} path="/about" component={About}>
- 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Home extends React.Component {
render() {
return (
<div>
home
</div>
)
}
}
class About extends React.Component {
render() {
return (
<div>
about
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom'
}
render() {
let {
msg } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
<NavLink to="/home/1/1" activeClassName='active996'>home</NavLink>
<NavLink to="/about/2" activeClassName='active996'>about</NavLink>
<Switch>
{
}
<Route exact path='/home/1/1' component={
Home}></Route>
<Route path='/about' component={
About}></Route>
<Redirect to='/about'></Redirect>
</Switch>
</div>
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
7.嵌套路由
- 注册子路由时要写上父路由的path值
- 路由的匹配时按照注册路由的顺序进行的
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class HomeDetails extends React.Component {
state = {
msg: '这里是home详情组件'
}
render() {
let {
msg } = this.state;
return (
<div className="home">
<h4>{
msg}</h4>
</div>
)
}
}
class Home extends React.Component {
state = {
msg: '这里是home组件'
}
render() {
let {
msg } = this.state;
return (
<div className="home">
<h3>{
msg}</h3>
<NavLink to='/home/details'>home详情</NavLink>
<Switch>
{
}
{
}
{
}
<Route to='/home/details' component={
HomeDetails}></Route>
</Switch>
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom'
}
render() {
let {
msg } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
<NavLink to='/home'>home</NavLink>
<Switch>
<Route path='/home' component={
Home}></Route>
</Switch>
</div >
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
8.向路由组件中传递参数
8.1向路由组件中传递params参数
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Detial extends React.Component {
state = {
msg: '这里是详情组件'
}
render() {
let {
msg } = this.state;
let {
props: {
match: {
params } } } = this;
console.log(params);
let infoArr = [];
for (const [key, value] of Object.entries(params)) {
infoArr.push(
<p key={
key}>{
key}-{
value}</p>
)
}
return (
<div className="detial">
<h3>{
msg}</h3>
{
infoArr}
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom',
arr: [
{
name: '张三', id: 0 },
{
name: '李四', id: 1 },
{
name: '王五', id: 2 }
]
}
render() {
let {
msg, arr } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
{
arr.map(item => {
return (
<NavLink to={
`/detial/${
item.id}/${
item.name}`} key={
item.id} activeClassName='detialActive' > {
item.name}</NavLink>
)
})
}
<Switch>
{
}
<Route path='/detial/:id/:name' component={
Detial}></Route>
</Switch>
</div >
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
8.2向路由组件中传递search参数
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
import qs from 'querystring';
class Detial extends React.Component {
state = {
msg: '这里是详情组件'
}
render() {
let {
msg } = this.state;
let {
props: {
location: {
search } } } = this;
let parseStr = qs.parse(search.substring(1));
let infoArr = [];
for (const [key, value] of Object.entries(parseStr)) {
infoArr.push(
<p key={
key}>{
key}-{
value}</p>
)
}
return (
<div className="detial">
<h3>{
msg}</h3>
{
infoArr}
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom',
arr: [
{
name: '张三', id: 0 },
{
name: '李四', id: 1 },
{
name: '王五', id: 2 }
]
}
render() {
let {
msg, arr } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
{
arr.map(item => {
return (
<NavLink to={
`/detial?id=${
item.id}&name=${
item.name}`} key={
item.id} activeClassName='detialActive' > {
item.name}</NavLink>
)
})
}
<Switch>
{
}
<Route path='/detial' component={
Detial}></Route>
</Switch>
</div >
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
8.3向路由组件中传递state参数
import React, {
Component } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter,Link, Route, NavLink, Switch, Redirect } from 'react-router-dom';
import './normalize.css';
class Detial extends React.Component {
state = {
msg: '这里是详情组件'
}
render() {
let {
msg } = this.state;
let {
props: {
location: {
state } } } = this;
let infoArr = [];
for (const [key, value] of Object.entries(state)) {
infoArr.push(
<p key={
key}>{
key}-{
value}</p>
)
}
return (
<div className="detial">
<h3>{
msg}</h3>
{
infoArr}
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom',
arr: [
{
name: '张三', id: 0 },
{
name: '李四', id: 1 },
{
name: '王五', id: 2 }
]
}
render() {
let {
msg, arr } = this.state;
return (
<div className="wrap">
<h2>{
msg}</h2>
{
arr.map(item => {
return (
<NavLink to={
{
pathname: '/detial',
state: {
id: item.id,
name: item.name
}
}} key={
item.id} activeClassName='detialActive' > {
item.name}</NavLink>
)
})
}
<Switch>
{
}
<Route path='/detial' component={
Detial}></Route>
</Switch>
</div >
)
}
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>, document.querySelector('#root'));
9.编程式导航
- 借助this.props.history对象上的API对操作路由跳转/前进/后退
- this.props.history.push()
- this.props.history.replace()
- this.props.history.goBack()
- this.props.history.goForward()
- this.props.history.go()
import React from 'react';
import './index.scss';
import {
Link, Route, NavLink, Switch, Redirect, withRouter } from 'react-router-dom';
import qs from 'querystring';
class Home extends React.Component {
state = {
msg: '这里是home组件'
}
render() {
let {
props: {
location: {
search, state }, match: {
params } } } = this;
if (!!state) {
console.log('state', state);
} else if (Object.keys(search).length > 0) {
console.log('search', qs.parse(search.substring(1)));
} else if (Object.keys(params).length > 0) {
console.log('params', params);
} else {
console.log('没有参数');
}
let {
msg } = this.state;
return (
<div className="home">
<h3>{
msg}</h3>
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'react-router-dom',
routeHTML: null,
obj: {
name: '张三', age: 18 }
}
goForward = () => {
let {
props: {
history } } = this;
history.goForward();
}
goBack = () => {
let {
props: {
history } } = this;
history.goBack();
}
go = (n) => {
let {
props: {
history } } = this;
history.go(n);
}
jumpHomeTypePush = (str, event) => {
let {
obj, routeHTML } = this.state;
let {
props: {
history } } = this;
switch (str) {
case 'no':
routeHTML = (<Route path="/home" component={
Home}></Route>);
history.push(`/home`);
break;
case 'params':
routeHTML = (<Route path="/home/:name/:age" component={
Home}></Route>);
history.push(`/home/${
obj.name}/${
obj.age}`);
break;
case 'search':
routeHTML = (<Route path="/home" component={
Home}></Route>);
history.push(`/home?name=${
obj.name}&age=${
obj.age}`);
break;
case 'state':
routeHTML = (<Route path="/home" component={
Home}></Route>);
history.push('/home', {
name: obj.name,
age: obj.age
});
break;
};
this.setState({
routeHTML
});
}
render() {
let {
msg, routeHTML } = this.state;
return (
<div className="wrap">
<h2>{
msg}
<button onClick={
this.goBack}>后退</button>
<button onClick={
this.goForward}>前进</button>
<button onClick={
() => {
this.go(-2)
}}>n(n>0前进n/n<0后退n)</button></h2>
<button onClick={
(event) => {
this.jumpHomeTypePush('no', event)
}
}>跳转到home组件-push方式</button>
<button onClick={
(event) => {
this.jumpHomeTypePush('params', event)
}
}>跳转到home组件-push方式-params参数传参</button>
<button onClick={
(event) => {
this.jumpHomeTypePush('search', event)
}
}>跳转到home组件-push方式-search参数传参</button>
<button onClick={
(event) => {
this.jumpHomeTypePush('state', event)
}
}>跳转到home组件-push方式-state参数传参</button>
<hr />
{
routeHTML
}
</div >
)
}
}
let WithRouterApp = withRouter(App);
ReactDOM.render(
<BrowserRouter>
<WithRouterApp />
</BrowserRouter>, document.querySelector('#root'));
10.BrowserRouter和HashRouter的区别
- 底层原理不一样
- BrowserRouter使用的是H5的history API,不兼容IE9以下版本
- HashRouter使用的是URL的哈希值
- path的表现形式不一样
- BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
- HashRouter的路径中包含#,例如:localhost:3000/#/demo/test
- 刷新后对路由的state参数的影响
- BrowserRouter没有任何影响,因为state保存在history对象中
- HashRouter刷新后会导致路由state参数丢失
- 备注: HashRouter可以用于解决一些路径错误相关的问题