React路由(含新老版对比)

React路由

源码地址:https://github.com/BLKNjyty/reactstudy

npm install --save react-router-dom

SPA

  1. 单页Web应用(single page web application,SPA)。

  2. 整个应用只有一个完整的页面

  3. 点击页面中的链接不会刷新页面,只会做页面的局部更新。

数据都需要通过ajax请求获取, 并在前端异步展现。

路由

理解:

1.一个路由就是一个映射关系(key:value)

  1. key为路径, value可能是function或component

分类

  1. 后端路由:

    1. 理解: value是function, 用来处理客户端提交的请求。

    2. 注册路由: router.get(path, function(req, res))

    3. 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据

  2. 前端路由:

    1. 浏览器端路由,value是component,用于展示页面内容。

    2. 注册路由:

    3. 工作过程:当浏览器的path变为/test时, 被前端路由器检测到了路径变化,当前路由组件就会变为Test组件

前端路由的原理

依赖于浏览器浏览历史工作,

见:其他 -前端路由的基石 ,由此可见,有两种方法控制浏览器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端路由的基石_history</title>
</head>
<body>
	<!-- 有onclick事件,不会跳转,只会调用函数 -->
	<a href="http://www.atguigu.com" onclick="return push('/test1') ">push test1</a><br><br>
	<button onClick="push('/test2')">push test2</button><br><br>
	<button onClick="replace('/test3')">replace test3</button><br><br>
	<button onClick="back()">&lt;= 回退</button>
	<button onClick="forword()">前进 =&gt;</button>

	<script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script>
	<script type="text/javascript">
		// let history = History.createBrowserHistory() //方法一,直接使用H5推出的history身上的API
		let history = History.createHashHistory() //方法二,hash值(锚点)
		
		//向浏览器的历史记录中放一些记录
		function push (path) {
			history.push(path)
			return false
		}
		//replace是替换栈顶的那条历史记录
		function replace (path) {
			history.replace(path)
		}

		function back() {
			history.goBack()
		}

		function forword() {
			history.goForward()
		}
		//监听url路径的变化
		history.listen((location) => {
			console.log('请求路由路径变化了', location)
		})
	</script>
</body>
</html>

react-router-dom

  1. react的一个插件库。

  2. 专门用来实现一个SPA应用。

  3. 基于react的项目基本都会用到此库。

基本用法

路由组件和基本组件

​ 1.写法

//一般
<Demo/>
//路由组件
<Routes>
		<Route path="/about" element={<About/>}/>
		<Route path="/home" element={<Home/>}/>
</Routes>

​ 2.放的位置应该不一样

​ 3.接受的props不同,一般组件一般是传递了什么就接收什么。

​ 路由组件接受三个固定属性:history,location,match

history:
	go:
	goBack:
	goForward:
	push:
	replace:
location:
	pathname:获取当前的路由路径
	search:
	state:
match:
	params:
	path:获取当前的路由路径
	url:获取当前的路由路径

简单案例

export default class App extends Component {
	render() {
		return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<div className="page-header"><h2>React Router Demo</h2></div>
					</div>
				</div>
				<div className="row">
					<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中靠路由链接实现切换组件--编写路由链接 */}
							<Link className="list-group-item" to="/about">About</Link>
							<Link className="list-group-item" to="/home">Home</Link>
						</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>
				</div>
			</div>
		)
	}
}

Home About

export default class Home extends Component {
	render() {
		return (
			<h3>我是Home的内容</h3>
		)
	}
}
export default class About extends Component {
	render() {
		console.log('About组件收到的props是',this.props);
		return (
			<h3>我是About的内容</h3>
		)
	}
}

NavLink

在React中靠路由链接实现切换组件–编写路由链接

​ About

​ Home

export default class App extends Component {
	render() {
		return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<Header/>
					</div>
				</div>
				<div className="row">
					<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中靠路由链接实现切换组件--编写路由链接 */}
							<NavLink activeClassName="atguigu" className="list-group-item" to="/about">About</NavLink>
							<NavLink activeClassName="atguigu" className="list-group-item" to="/home">Home</NavLink>
						</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>
				</div>
			</div>
		)
	}
}
export default class Header extends Component {
	render() {
		// console.log('Header组件收到的props是',this.props);
		return (
			<div className="page-header"><h2>React Router Demo</h2></div>
		)
	}
}

封装自己的NavLink

export default class MyNavLink extends Component {
	render() {
		// console.log(this.props);
		return (
			<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/>
		)
	}
}
export default class App extends Component {
	render() {
		return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<Header/>
					</div>
				</div>
				<div className="row">
					<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中靠路由链接实现切换组件--编写路由链接 
								标签体的值是key为children的标签属性的值传递过去了,MyNavLink组件的{...this.props}直接接受了这个参数:
									children:About
							*/}
							<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>
				</div>
			</div>
		)
	}
}

Switch

{/* 注册路由,/home下有两个路由组件,加入switch之后,匹配到第一个就不会再匹配了 */}
								<Switch>
									<Route path="/about" component={About}/>
									<Route path="/home" component={Home}/>
									<Route path="/home" component={Test}/>
								</Swtch>

样式丢失

原因:

​ 路由多级时这时刷新,样式会丢失!

​ 原因:

​ index.html的样式引入改为,点表示当前目录

​ 解决办法:

​ 1.将index.html的样式引入改为

​ 2.将index.html的样式引入改为

​ 3.使用HashRouter代替BrowserRouter,因为将url的#后的值视为无效

​ 当请求的东西不存在,则把public下的index.html返回 (这是脚手架设置的)

export default class App extends Component {
	render() {
		return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<Header/>
					</div>
				</div>
				<div className="row">
					<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="/atguigu/about">About</MyNavLink>
							<MyNavLink to="/atguigu/home">Home</MyNavLink>
						</div>
					</div>
					<div className="col-xs-6">
						<div className="panel">
							<div className="panel-body">
								{/* 注册路由
								路由多级时这时刷新,样式会丢失!
								原因:
								index.html的样式引入改为<link rel="stylesheet" href="./css/bootstrap.css">,点表示当前目录
								解决办法:
								1.将index.html的样式引入改为<link rel="stylesheet" href="/css/bootstrap.css">
								2.将index.html的样式引入改为<link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.css">
								3.使用HashRouter代替BrowserRouter,因为将url的#后的值视为无效
								当请求的东西不存在,则把public下的index.html返回 (这是脚手架设置的)*/}
								<Switch>
									<Route path="/atguigu/about" component={About}/>
									<Route path="/atguigu/home" component={Home}/>
								</Switch>
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

exact

{/* 注册路由 exact开启了严格匹配 */}
<Switch>
	<Route exact path="/about" component={About}/>
	<Route exact path="/home" component={Home}/>
</Switch>

Rediect

{/* 注册路由 Redirect 谁都匹配不上  跳转的路由*/}
<Switch>
	<Route path="/about" component={About}/>
	<Route path="/home" component={Home}/>
	<Redirect to="/about"/>
</Switch>

二级路由

home路由下面增加Message和News路由

export default class Home extends Component {
	render() {
		return (
				<div>
					<h3>我是Home的内容</h3>
					<div>
						<ul className="nav nav-tabs">
							{/* 在父路由的下面接着写路由
							/home/news 模糊匹配,和Home路由也匹配,所以父组件也会展示
							/home/news 模糊匹配,又和news路由匹配
							所以不能开启严格匹配
							*/}
							<li>
								<MyNavLink to="/home/news">News</MyNavLink>
							</li>
							<li>
								<MyNavLink to="/home/message">Message</MyNavLink>
							</li>
						</ul>
						{/* 注册路由 */}
						<Switch>
							<Route path="/home/news" component={News}/>
							<Route path="/home/message" component={Message}/>
							<Redirect to="/home/news"/>
						</Switch>
					</div>
				</div>
			)
	}
}

路由组件传递参数

点击Message页面的详细信息链接在下面显示detail,并且把参数传递过去

params参数

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}
	render() {
		const {messageArr} = this.state
		return (
			<div>
				<ul>
					{
						messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>
									{/* 向路由组件传递params参数 */}
									<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
								</li>
							)
						})
					}
				</ul>
				<hr/>
				{/* 声明接收params参数 */}
				<Route path="/home/message/detail/:id/:title" component={Detail}/>
			</div>
		)
	}
}
const DetailData = [
	{id:'01',content:'你好,中国'},
	{id:'02',content:'你好,尚硅谷'},
	{id:'03',content:'你好,未来的自己'}
]
export default class Detail extends Component {
	render() {
		console.log(this.props);
		// 接收params参数
		const {id,title} = this.props.match.params
		const findResult = DetailData.find((detailObj)=>{
			//查找的条件
			return detailObj.id === id
		})
		return (
			<ul>
				<li>ID:{id}</li>
				<li>TITLE:{title}</li>
				<li>CONTENT:{findResult.content}</li>
			</ul>
		)
	}
}

search参数(query参数)

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}
	render() {
		const {messageArr} = this.state
		return (
			<div>
				<ul>
					{
						messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>


									{/* 向路由组件传递search参数 */}
									<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>

								</li>
							)
						})
					}
				</ul>
				<hr/>
				{/* 声明接收params参数 */}
				{/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}

				{/* search参数无需声明接收,正常注册路由即可 */}
				<Route path="/home/message/detail" component={Detail}/>

			</div>
		)
	}
}
// qs有两个有用的功能:
//针对urlencoding编码:key=value&key1=value1==>qs
//将json对象格式转化为此编码格式:qs.stringfy(urlencoding);反过来qs.paese(json)
const DetailData = [
	{id:'01',content:'你好,中国'},
	{id:'02',content:'你好,尚硅谷'},
	{id:'03',content:'你好,未来的自己'}
]
export default class Detail extends Component {
	render() {
		console.log(this.props);
		// 接收search参数
		const {search} = this.props.location
		const {id,title} = qs.parse(search.slice(1))

		const findResult = DetailData.find((detailObj)=>{
			return detailObj.id === id
		})
		return (
			<ul>
				<li>ID:{id}</li>
				<li>TITLE:{title}</li>
				<li>CONTENT:{findResult.content}</li>
			</ul>
		)
	}
}

state参数

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}
	render() {
		const {messageArr} = this.state
		return (
			<div>
				<ul>
					{
						messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>

									{/* 向路由组件传递state参数 */}
									<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>

								</li>
							)
						})
					}
				</ul>
				<hr/>

				{/* state参数无需声明接收,正常注册路由即可 */}
				<Route path="/home/message/detail" component={Detail}/>

			</div>
		)
	}
}
const DetailData = [
	{id:'01',content:'你好,中国'},
	{id:'02',content:'你好,尚硅谷'},
	{id:'03',content:'你好,未来的自己'}
]
export default class Detail extends Component {
	render() {
		console.log(this.props);
		// 接收state参数,刷新页面  上述三种参数传递方式 参数都不会丢失
		//为防止查出来是undefined(比如清除了缓存或者就没传递数据),则使用{}空对象,防止浏览器报错
		//HashRouter路由会导致参数的丢失
		const {id,title} = this.props.location.state || {}

		const findResult = DetailData.find((detailObj)=>{
			return detailObj.id === id
		}) || {}
		return (
			<ul>
				<li>ID:{id}</li>
				<li>TITLE:{title}</li>
				<li>CONTENT:{findResult.content}</li>
			</ul>
		)
	}
}

编程时路由导航

即不靠路由标签Link或者MyNavLink 标签

自己写函数完成路由的跳转

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}

	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})
		
	}

	back = ()=>{
		this.props.history.goBack()
	}

	forward = ()=>{
		this.props.history.goForward()
	}

	go = ()=>{
		this.props.history.go(-2)
	}

	render() {
		const {messageArr} = this.state
		return (
			<div>
				<ul>
					{
						messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>
									{/* 向路由组件传递state参数 */}
									<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>

									&nbsp;<button onClick={()=> this.pushShow(msgObj.id,msgObj.title)}>push查看</button>
									&nbsp;<button onClick={()=> this.replaceShow(msgObj.id,msgObj.title)}>replace查看</button>
								</li>
							)
						})
					}
				</ul>
				<hr/>
				{/* 声明接收params参数 */}
				{/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}

				{/* search参数无需声明接收,正常注册路由即可 */}
				{/* <Route path="/home/message/detail" component={Detail}/> */}

				{/* state参数无需声明接收,正常注册路由即可 */}
				<Route path="/home/message/detail" component={Detail}/>

				<button onClick={this.back}>回退</button>&nbsp;
				<button onClick={this.forward}>前进</button>&nbsp;
				<button onClick={this.go}>go</button>

			</div>
		)
	}
}

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)

//withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
//withRouter的返回值是一个新组件
//要不然一般组件就没有路由组件的history这些api

BrowerRouter和HashRouter路由器的区别

1.底层原理不一样:

​ BrowerRouter使用的时h5的history(不是this.props.history这个,这个是React对h5的history的封装),不兼容ie9以及以下版本

​ HashRouter使用的时URL的哈希值

2.url表现形式不一样:

​ BrowerRouter没有#,如:localhost:3000/demo/test

​ HashRouter的路径包含#,如:localhost:3000/#/demo/test

3.刷新后对路由state参数的影响(重要)

​ BrowerRouter没有影响,因为statev保存在state对象中

​ HashRouter刷新为导致state参数丢失

4.HashRouter可以用来解决一些路径错误的相关问题(比如样式丢失的问题)

React6路由

区别

element代理component

Routes

1.代替Switch

2.和Route配合使用,Route外边必须包裹Routes

3.Route相当于if语句,如路径和当前的url匹配,则呈现对应的组件

4.属性用于指定:路径匹配知否忽略大小写(more那位false)

5.当路由变化是,Routes匹配所有的Route元素找到最佳的匹配并呈现组件

6.Routes也可以嵌套使用,且配合useRoutes配置路由表,但需要通过Outlet组件来渲染子路由

重要:使用useRoutes

路由表

export default [
    {
      path:'/about',
      element:<About/>
    },
    {
      path:'/home',
      element:<Home/>,
      children:[
        {
            path:'news',
            element:<News/>
        },
        {
          path:'message',
          element:<Message/>,
          children:[
            {
              // path:'detail/:id/:title',
              path:'detail',
              element:<Detail/>
            }
          ]
      }
      ]
    },
    {
      path:'/',
      element:<Navigate to="/about"/>
    }
  ]

路由表暴露在App.jsx中,

import { useRoutes} from 'react-router-dom'
 // 路由表,根据路由表生成路由
  const element=useRoutes(routes)
  
  //在函数组件的return片段需要注册路由的片段中添加
  {element}

例子:

end:子路由匹配到,父路由就不高亮了。

return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<div className="page-header"><h2>React Router Demo</h2></div>
					</div>
				</div>
				<div className="row">
					<div className="col-xs-2 col-xs-offset-2">
						<div className="list-group">

              <NavLink className={computedClassName} to="/about">About</NavLink>
							<NavLink className={computedClassName} end to="/home">Home</NavLink>
						</div>
					</div>
					<div className="col-xs-6">
						<div className="panel">
							<div className="panel-body">
                {element}
							</div>
						</div>
					</div>
				</div>
			</div>
		)
        
function  computedClassName({isActive}){
  //console.log(isActive)
  return isActive ? 'list-group-item atguigu' : 'list-group-item' 
}        

Navigate代替Redirect

只要被渲染在页面上就会切换视图

除了to属性,还有replace属性。

//1.在路由表中,表示url以/结尾默认展示about组件
{
      path:'/',
      element:<Navigate to="/about"/>
    }
//2.满足条件即跳转,比如当前页面的sum变为2时,自动跳转为about组件(替换当前的home组件)
export default function Home() {
	const [sum, setSum] = React.useState(1)


	return (
		<div>
			<h3>我是Home的内容</h3>
			{/* <h4>{this.state.sum}</h4> */}
			{sum === 2 ? <Navigate to="/about" replace={false} /> : <h4>当前的sum值是{sum}</h4>}
			<button onClick={() => setSum(sum => sum + 1)}>点击将sum变为2</button>
		</div>

	)

}

NavLink高亮

 computedClassName({isActive}){
    console.log(isActive)
    return isActive ? 'list-group-item atguigu' : 'list-group-item' 
 }
//不可以在标签里直接用activeClassName="atguigu" 这种形式了
<NavLink className={this.computedClassName} to="/home">Home</NavLink>

参数携带

点击message组件中的链接,在下方展示另外一个组件,里面有传递过去的内容

export default function Message() {
	const [messageArr,setessageArr] = React.useState(
		 [
			{ id: '01', title: '消息1' },
			{ id: '02', title: '消息2' },
			{ id: '03', title: '消息3' },
		 ]
		)
	return (
		<div>
			<ul>
				{
					messageArr.map((msgObj) => {
						return (
							<li key={msgObj.id}>
								{/* 向路由组件传递params参数 */}
								{/* <Link to={`detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}
								{/* search参数 */}
								{/* <Link to={`detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}
								<Link to="detail" state={{
									id: msgObj.id,
									title: msgObj.title,
								}}>{msgObj.title}</Link>
							</li>
						)
					})
				}
			</ul>
			<hr />
			<Outlet />
		</div>
	)
}
{
      path:'/home',
      element:<Home/>,
      children:[
        {
            path:'news',
            element:<News/>
        },
        {
          path:'message',
          element:<Message/>,
          children:[
            {
            //params传参数需要声明,其他两种不需要
              // path:'detail/:id/:title',
              path:'detail',
              element:<Detail/>
            }
          ]
      }
      ]
},
const DetailData = [
	{ id: '01', content: '你好,中国' },
	{ id: '02', content: '你好,尚硅谷' },
	{ id: '03', content: '你好,未来的自己' }
]
export default function Detail() {

	// console.log(this.props);
	//`接收params参数
	// const { id, title } = useParams()
	
	//接收search参数,用于更新接收到的参数setSearch(`id=0001&title=hahha`)
	// const  [search,setSearch]=useSearchParams()
	// const id=search.get('id')
	// const title=search.get('title')

	//state对象
	const {state:{id,title}}=useLocation()
	const findResult = DetailData.find((detailObj) => {
		//查找的条件
		return detailObj.id === id
	})
	return (
		<ul>
			<li>ID:{id}</li>
			<li>TITLE:{title}</li>
			<li>CONTENT:{findResult.content}</li>
		</ul>
	)
}

函数式路由导航

不需要Link navLink,比如点击图片跳转的时候或者点击一个自定义标签跳转的时候

使用useNavigate进行自定义跳转,同时这种形式只能接收state参数,可以设置跳转类型push/replace

export default function Message() {
	const [messageArr,setessageArr] = React.useState(
		 [
			{ id: '01', title: '消息1' },
			{ id: '02', title: '消息2' },
			{ id: '03', title: '消息3' },
		 ]
		)
	const navigate=useNavigate()
	function showDetail(msgObj){
		navigate('detail',{
			replace:false,
			// paramhe search参数不能这样写,直接写在路径上
			state:{
				id:msgObj.id,
				title:msgObj.title
			}
		})
	}

	return (
		<div>
			<ul>
				{
					messageArr.map((msgObj) => {
						return (
							<li key={msgObj.id}>
								<Link to="detail" state={{
									id: msgObj.id,
									title: msgObj.title,
								}}>{msgObj.title}</Link>
								<button onClick={()=>showDetail(msgObj)}>展示详情</button>
							</li>
						)
					})
				}
			</ul>
			<hr />
			<Outlet />
		</div>
	)

}
路由跳转操作
export default function Header() {
    const navigate=useNavigate()

    function back(){
        navigate(-1)
    }

    function forward(){
        navigate(1)
    }
    return (
        <div className="col-xs-offset-2 col-xs-8">
            <div className="page-header"><h2>React Router Demo</h2></div>
            <button onClick={forward}>前进</button>
            <button onClick={back}>后退</button>
        </div>
    )
}

useInRouterContext

如果组件在Router的上下文呈现,则其返回true,否则返回false

//一般,表示APP 及其子组件都是在上下文环境中,即被被BrowserRouter包裹(不区分路由和非路由组件)
ReactDOM.render(
	<BrowserRouter>
		<App/>
	</BrowserRouter>,
	document.getElementById('root')
)

useNavigationType

返回用户是如何来到当前页面的

返回值:

​ pop,push,replace

备注:

​ pop是指在浏览器中直接打开路由组件(刷新当前页面)

useOutlet

作用:用来呈现当前组件中渲染的嵌套路由组件

const result=useOutLet()
console.log(result)
//如果嵌套路由组件已经挂在,则显示嵌套路由对象,否则为null

useResolvedPath

解析一个url,解析其中的path,search,hash

本文参考b站尚硅谷视频 链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值