1. 安装指定版本的React路由
在项目终端里输入npm install react-router-dom@^5.3.0 --save
检查是否安装成功
2. 渲染路由组件
创建Home组件
import React, { Component } from 'react'
export default class Home extends Component {
render() {
return (
<div>
<h1>我是Home组件</h1>
</div>
)
}
}
创建About组件
import React, { Component } from 'react'
export default class About extends Component {
render() {
return (
<div>
<h1>我是About组件</h1>
</div>
)
}
}
在App.js文件中引入路由和组件
import React, { Component } from 'react'
import {BrowserRouter as Router,Route,Link} from "react-router-dom" // 引入路由
import Home from "./Home"
import About from './About'
export default class App extends Component {
render() {
return (
<Router>
<div>
<h1>路由demo</h1>
<Link to="/home">home</Link><br/>
<Link to="/about">about</Link>
<Route path="/home" component={Home}></Route>
<Route path="/about" component={About}></Route>
</div>
</Router>
)
}
}
渲染路由组件的时候,出现了一个问题,Link能够跳转到相应路由组件的url,但是页面不渲染路由组件,必须刷新一下页面才会渲染路由组件。解决方法是在根组件中,把react的严格模式标签移除。
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);
效果
3. 嵌套路由
在Home组件中,再渲染两个路由组件,需要使用嵌套路由。match可以拿到父路由的路径。
import React, { Component } from 'react'
import {Link,Route} from "react-router-dom"
function First(){
return(
<div>我是home中的首页</div>
)
}
function Consult(){
return(
<div>我是home中的咨询页</div>
)
}
export default class Home extends Component {
render() {
// match可以拿到父路由的路径
const {match} = this.props
return (
<div>
<h1>我是Home组件</h1>
<Link to={`${match.url}/first`}>home中的首页</Link><br/>
<Link to={`${match.url}/consult`}>home中的咨询页</Link>
<Route path={`${match.url}/first`} component={First}></Route>
<Route path={`${match.url}/consult`} component={Consult}></Route>
</div>
)
}
}
match的返回结果是一个对象,里面包含了当前组件的url地址。
效果
4. 路由传参
路由传参有三种方式,params、query/search、state。
4.1 params
在Demo页面中,使用props获取路由中传递的参数,参数位置:match.params
效果:点击demo标签,可以在demo页面中渲染出路由中的参数”123“
4.2 query/search
参数之间使用"&"进行分隔
在Demo页面中,路由参数位置:location.search
可以安装querystring插件来解析url参数
在项目终端里输入:npm i -save-dev query-string
效果
4.3 state
state适合传复杂的数据,比如对象
效果
5. 非路由组件的跳转
如果不使用Link标签,实现路由跳转有三种方式。
5.1 将button标签定义为路由组件
普通的button按钮,没有history属性,无法完成路由跳转,所以需要将button按钮定义为路由组件。
// About路由组件
import React, { Component } from 'react'
export default class About extends Component {
render() {
return (
<div>
<h1>我是About组件</h1>
</div>
)
}
}
将button标签定义为路由组件,点击button按钮后,跳转到About页面
import React, { Component } from 'react'
import {BrowserRouter as Router,Route,Link, Switch} from "react-router-dom" // 引入路由
import About from "./About"
function News(props){
function nav(){
props.history.push("/demo/consult")
}
return(
<div>
<h1 onClick={nav}>我是News组件</h1>
</div>
)
}
function Conuslt(){
return(
<div>
<h1>我是Consult组件</h1>
</div>
)
}
export default class App extends Component {
render() {
return (
<Router>
<div>
<Link to="/demo">demo</Link><br/>
// 将button标签定义为路由组件
<Route render={({history})=>
<button onClick={()=>history.push("/about")}>跳转到About页面</button>
}></Route>
<Switch>
<Route path="/demo" render={()=>(
<div>
<h1>我是Demo组件</h1>
<Route path="/demo/news" component={News}></Route>
<Route path="/demo/consult" component={Conuslt}></Route>
</div>
)}></Route>
<Route path="/about" component={About}></Route>
</Switch>
</div>
</Router>
)
}
}
效果
5.2 useHistory
useHistory能使路由跳转变得更轻松。useHistory需要在路由版本高于5.1.0,且低于6.0时才能使用。
注意: useHistory不适用于组件本身,只能在子组件中使用,所以button按钮需要单独封装成一个子组件。
// Button.jsx
import React from 'react'
import { useHistory } from 'react-router-dom'
export default function Button() {
const history = useHistory()
function jump(){
history.push("/about")
}
return (
<button onClick={jump}>跳转</button>
)
}
// About.jsx
import React, { Component } from 'react'
export default class About extends Component {
render() {
return (
<div>
<h1>我是About组件</h1>
</div>
)
}
}
// App.js文件
import React from 'react'
import {BrowserRouter as Router,Route,Link, Switch} from "react-router-dom" // 引入路由
import About from "./About"
import MyButton from "./Button"
function News(props){
function nav(){
props.history.push("/demo/consult")
}
return(
<div>
<h1 onClick={nav}>我是News组件</h1>
</div>
)
}
function Conuslt(){
return(
<div>
<h1>我是Consult组件</h1>
</div>
)
}
export default function App() {
return (
<Router>
<div>
<Link to="/demo">demo</Link><br/>
<MyButton/>
<Switch>
<Route path="/demo" render={()=>(
<div>
<h1>我是Demo组件</h1>
<Route path="/demo/news" component={News}></Route>
<Route path="/demo/consult" component={Conuslt}></Route>
</div>
)}></Route>
<Route path="/about" component={About}></Route>
</Switch>
</div>
</Router>
)
}
效果
点击跳转按钮渲染About页面
5.3 withRouter
将组件传入到withRouter函数中,可以把组件变为路由组件。
import React ,{Component} from 'react'
import {BrowserRouter as Router,Route,Link, Switch, withRouter} from "react-router-dom" // 引入路由
import About from "./About"
function News(props){
function nav(){
props.history.push("/demo/consult")
}
return(
<div>
<h1 onClick={nav}>我是News组件</h1>
</div>
)
}
function Conuslt(){
return(
<div>
<h1>我是Consult组件</h1>
</div>
)
}
class App extends Component {
jump=()=>{
this.props.history.push("/about")
}
render(){
return (
<Router>
<div>
<Link to="/demo">demo</Link><br/>
<button onClick={this.jump}>跳转</button>
<Switch>
<Route path="/demo" render={()=>(
<div>
<h1>我是Demo组件</h1>
<Route path="/demo/news" component={News}></Route>
<Route path="/demo/consult" component={Conuslt}></Route>
</div>
)}></Route>
<Route path="/about" component={About}></Route>
</Switch>
</div>
</Router>
)
}
}
export default withRouter(App)
在根组件index中,需要将App路由组件写在Router标签中,因为withRouter返回的是一个路由组件。
效果
点击跳转,渲染About页面
6. 路由懒加载
7. 路由配置项文件
安装插件:npm install react-router-config
创建routerConfig.js文件
效果