【React】React学习笔记四:React 路由

学习视频链接

一、前言

1.SPA的理解

    -  单页Web应用(single page web application,SPA)。
    -  整个应用只有一个完整的页面。
    -  点击页面中的链接不会刷新页面,只会做页面的局部更新。
    -  数据都需要通过ajax请求获取, 并在前端异步展现。

2.路由的理解

(1)什么是路由?

一个路由就是一个映射关系(key:value)。其中:key为路径, value可能是function或component。

(2)路由分类

后端路由:
    -  理解: value是function, 用来处理客户端提交的请求
    -  注册路由: router.get(path, function(req, res))
    -  工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
前端路由:
    -  浏览器端路由,value是component,用于展示页面内容
    -  注册路由: <Route path="/test" component={Test}>
    -  工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件

3.react-router-dom的理解

react的一个插件库,专门用来实现一个SPA应用。基于react的项目基本都会用到此库。

二、react-router-dom相关API

内置组件

1.<BrowserRouter>
2.<HashRouter>
3.<Route>
4.<Redirect>
5.<Link>
6.<NavLink>
7.<Switch>

其它

1.history对象
2.match对象
3.withRouter函数

三、基本路由

1.路由的基本使用

1)明确好界面中的导航区、展示区
(2)导航区的a标签改为Link标签
		<Link to="/xxxxx">Demo</Link>3)展示区写Route标签进行路径的匹配		
		<Route path='/xxxx' component={Demo}/>4<App>的最外侧包裹了一个<BrowserRouter><HashRouter>

2.路由组件与一般组件

1)写法不同:
		一般组件:<Demo/>
		路由组件:<Route path="/demo" component={Demo}/>2)存放位置不同:
		一般组件:components
		路由组件:pages
(3)接收到的props不同:
		一般组件:写组件标签时传递了什么,就能收到什么
		路由组件:接收到三个固定的属性
			history:
						go: ƒ go(n)
						goBack: ƒ goBack()
						goForward: ƒ goForward()
						push: ƒ push(path, state)
						replace: ƒ replace(path, state)
			location:
						pathname: "/about"
						search: ""
						state: undefined
			match:
						params: {}
						path: "/about"
						url: "/about"

3.NavLink与封装NavLink

NavLink可以实现路由链接的高亮,通过activeClassName指定样式名

// App.jsx
import Home from './pages/Home' //Home是路由组件
import About from './pages/About' //About是路由组件
import MyNavLink from './components/MyNavLink'


<div className="col-xs-2 col-xs-offset-2">
	<div className="list-group">

		{/* 原生html中,靠<a>跳转不同的页面 */}
		{/* <a className="list-group-item" href="./about.html">About</a>
		<a className="list-group-item active" href="./home.html">Home</a> */}

		{/* 在React中靠路由链接实现切换组件--编写路由链接 */}
		<MyNavLink to="/about">About</MyNavLink>
		<MyNavLink to="/home">Home</MyNavLink>
	</div>
</div>
<div className="col-xs-6">
	<div className="panel">
		<div className="panel-body">
			{/* 注册路由 */}
			<Route path="/about" component={About}/>
			<Route path="/home" component={Home}/>
		</div>
	</div>
</div>
// /components/MyNavLink/index.jsx
import React, { Component } from 'react'
import {NavLink} from 'react-router-dom'

export default class MyNavLink extends Component {
	render() {
		// console.log(this.props);
		return (
			<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/>
		)
	}
}

4.Switch的使用

通常情况下,path和component是一一对应的关系。Switch可以提高路由匹配效率(单一匹配)。

{/* 注册路由 */}
<Switch>
	<Route path="/about" component={About}/>
	<Route path="/home" component={Home}/>
	<Route path="/home" component={Test}/>
</Switch>

5.解决多级路径刷新页面样式丢失的问题

1public/index.html 中 引入样式时不写 .// (常用)
(2public/index.html 中 引入样式时不写 ./%PUBLIC_URL% (常用)
(3)使用HashRouter

6.路由的严格匹配与模糊匹配

1)默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
(2)开启严格匹配:<Route exact={true} path="/about" component={About}/>3)严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由

7.Redirect的使用

重定向设置默认选择的路由

1)一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
(2)具体编码:
		<Switch>
			<Route path="/about" component={About}/>
			<Route path="/home" component={Home}/>
			<Redirect to="/about"/>
		</Switch>

四、嵌套路由(多级路由)

1)注册子路由时**要写上父路由的path值**2)路由的匹配是按照**注册路由的顺序**进行的

五、向路由组件传递参数

1.params参数

路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
接收参数this.props.match.params

2.search参数

路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数this.props.location.search

备注:获取到的search是urlencoded编码字符串,需要借助querystring解析

3.state参数

路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数this.props.location.state

备注:刷新也可以保留住参数

六、路由跳转

1.编程式路由导航

借助this.prosp.history对象上的API对操作路由跳转、前进、后退

-this.props.history.push()
-this.props.history.replace()
-this.props.history.goBack()
-this.props.history.goForward()
-this.props.history.go()
// 不留下痕迹
replaceShow = (id,title)=>{
	//replace跳转+携带params参数
	//this.props.history.replace(`/home/message/detail/${id}/${title}`)

	//replace跳转+携带search参数
	// this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)

	//replace跳转+携带state参数
	this.props.history.replace(`/home/message/detail`,{id,title})
}

// 不留下痕迹
pushShow = (id,title)=>{
	//push跳转+携带params参数
	// this.props.history.push(`/home/message/detail/${id}/${title}`)

	//push跳转+携带search参数
	// this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)

	//push跳转+携带state参数
	this.props.history.push(`/home/message/detail`,{id,title})
	
}

2.一般组件具备路由组件所特有的API

withRouter可以加工一般组件,让一般组件具备路由组件所特有的API。withRouter的返回值是一个新组件。

class Header extends Component {
	back = ()=>{
		this.props.history.goBack()
	}
	forward = ()=>{
		this.props.history.goForward()
	}
	go = ()=>{
		this.props.history.go(-2)
	}
	render() {
		console.log('Header组件收到的props是',this.props);
		return (
			<div className="page-header">
				<h2>React Router Demo</h2>
				<button onClick={this.back}>回退</button>&nbsp;
				<button onClick={this.forward}>前进</button>&nbsp;
				<button onClick={this.go}>go</button>
			</div>
		)
	}
}

export default withRouter(Header)

七、BrowserRouter与HashRouter的区别

1.底层原理不一样:
     -  BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
     -  HashRouter使用的是URL的哈希值。
2.path表现形式不一样
     -  BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
     -  HashRouter的路径包含#,例如:localhost:3000/#/demo/test
3.刷新后对路由state参数的影响
     -  BrowserRouter没有任何影响,因为state保存在history对象中
     -  HashRouter刷新后会导致路由state参数的丢失,因为没有用history的API
4.备注:HashRouter可以用于解决一些路径错误相关的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值