找回密码
 会员注册
查看: 20|回复: 0

React路由使用

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-10-11 21:34:25 | 显示全部楼层 |阅读模式
Routerreact-router-dom是一个处理页面跳转的三方库,在使用之前需要先安装到我们的项目中:#npmnpminstallreact-router-dom@6#yarnyarnaddreact-router-dom@6简单路由使用路由时需要为组件指定一个路由的path,最终会以path为基础,进行页面的跳转。具体使用先看个简单示例,该示例比较简单就是两个Tab页面的来回切换。///导入路由import{Link}from'react-router-dom'functionApp(){return( 路由练习 {/*link页面展示时,是个a标签*/}Tab1///覆盖:渲染tab1组件Tab2///覆盖:渲染tab2组件);}///路由页面1exportdefaultfunctionTab1(params){return(//文档中,元素是唯一的,所以不能出现一个以上的元素 我是Tab1 );}///路由页面2exportdefaultfunctionTab2(params){return( 我是Tab2 );}///在index.js中配置路由import{BrowserRouter,Routes,Route}from'react-router-dom'importTab1from'./pages/Tab1.jsx'importTab2from'./pages/Tab2.jsx'constroot=ReactDOM.createRoot(document.getElementById('root'));root.render( }/>///兄弟路由}/>///兄弟路由}/>///兄弟路由);最终交互时,上述路由配置会出现彼此覆盖的情况,如下图:为了保证App组件,不会在Tab1和Tab2切换时被覆盖需要使用嵌套路由。嵌套路由嵌套路由,可以保证子路由共享父路由的界面而不会覆盖。为此React提供了Outlet组件,将其用于父组件中可以为子路由的元素占位,并最终渲染子路由的元素。Outlet渲染一个子路由的元素import{Link,Outlet}from'react-router-dom'functionApp(){return( 路由练习 {/*link页面展示时,是个a标签*/}Tab1Tab2{/*此时尚不能实现共享APPUI的同时渲染出Tab1和Tab2,还需要使用保证父路由,在子路由交换时,仍然存在*/});}///index.jsconstroot=ReactDOM.createRoot(document.getElementById('root'));root.render( }>{/*孩子路由,url为:/+孩子的path*/}}/>}/>);最终效果如下图:未匹配路由通过path='*',实现没有其他路由匹配时,对其进行匹配。root.render( }>{/*孩子路由,url为:/+孩子的path*/}}/>}/>未匹配到路由时,会跳转此处。}/>);效果如图:路由传参数通过路由传递参数到组件中///模拟数据constdataList=[{id:20220101,content:'笔记1'},{id:20220102,content:'笔记2'},{id:20220103,content:'笔记3'},]exportdefaultfunctiongetTodoList(params){returndataList}exportfunctionfindTodoItem(params){returndataList.find((value)=>value.id===params)}///组件Tab2中定义列表exportdefaultfunctionTab2(params){letlist=getTodoList()return({list.map((item)=>({/*子路由形如:'/Tab2/20220103'*/}{item.content}))}{/*渲染一个子路由的元素*/});}///注册列表项的子路由root.render( }>{/*孩子路由,url为:/+孩子的path*/}}/>}>}/>未匹配到该路由请先设置路由页面}/>);///定义Tab2子组件ItemDetailimport{useParams}from'react-router-dom'exportfunctionItemDetail(){//点击每一项的链接,注意:URL 发生了变化,但新的组件尚未显示///需要父组件中添加///HOOK获取路由中的参数,形如{itemId:'20220102'}letparams=useParams()letcontent=findTodoItem(parseInt(params.itemId)).contentreturn( 笔记详情 这是我于{params.itemId},记录的笔记他的内容为{content})}索引路由当我们切换至Tab1再切回Tab2后,笔记详情页面将空白,效果如下:可以通过索引路由填补空白,具体只需:root.render( }>{/*孩子路由,url为:/+孩子的path*/}}/>}>{/*索引路由有index无path*/}请选择一个笔记查看它的详情}/>}/>未匹配到该路由请先设置路由页面}/>);如此当我们重复上述操作时便会呈现如下效果:当父路由匹配,但其他子路由都不匹配时,由索引路由匹配。索引路由是父路由的默认子路由。当用户尚未单击导航列表中的一项时,会呈现索引路由。活动链接与Link功能一致,差异是可以设置点击后的颜色exportdefaultfunctionTab2(params){letlist=getTodoList()return({list.map((item)=>({/*{item.content}*/}({color:isActive"red":""})}to={`/Tab2/${item.id}`}>{item.content}))});}搜索参数搜索参数类似于 URL 参数,形如/loginsuccess=1exportdefaultfunctionTab2(params){letlist=getTodoList()///和React.useState很像let[searchParams,setSearchParams]=useSearchParams();return({/*搜索框:随着输入设置搜索参数*/}{lettext=event.target.valueif(text){setSearchParams({text})}else{setSearchParams({})}}}/>{list.filter((item)=>{lettxt=searchParams.get('text')if(!txt)returntruereturnitem.content.startsWith(txt)}).map((item)=>({/*{item.content}*/}({color:isActive"red":""})}to={`/Tab2/${item.id}`}>{item.content}))});}随着我们输入apple, 路由的地址将变为/Tab2text=apple触发路由重新呈现。当我们在输入框输入字符时,便会触发列表的过滤显示:自定义行为上述UI在交互过程中,当我们点击Tab1和Tab2进行切换时,或者点击apple或appet时,会出现输入框被清空,且列表不再被过滤的问题。react-router提供了useLocation方法,它返回浏览器显示的url信息。通过它可以获取浏览器url中的搜索参数,从而进行暂存,在具体组件内,可以通过useSearchParams获取到暂存的值。具体方式,通过自定义组件包装NavLink或Link来实现。///1.自定义`QueryLink`组件importReact,{Component}from'react';import{useLocation,NavLink}from"react-router-dom";exportdefaultfunctionQueryLink({to,...props}){///代表当前浏览器显示的url// location内容:{pathname:'/Tab2', search:'text=ad', hash:'', state: null, key:'dhvg8xme'}letlocation=useLocation()//to='/Tab2text=ad'return}//2.替换`tab1`、`tab2`的linkorNavlinkTab1Tab2//3.替换列表项的linkorNavlink({color:isActive"red":""})}to={`/Tab2/${item.id}`}>{item.content}useNavigate上述示例中,路由的切换采用Link或者NavLink,但当我们的页面元素不使用Link时,比如使用Button,此时便需要使用采用useNavigate。同上可以配合useLocation保存搜索字段。exportfunctionItemDetail(){//点击每一项的链接,注意:URL 发生了变化,但新的组件尚未显示///需要父组件中添加letparams=useParams()letcontent=findTodoItem(parseInt(params.itemId)).content///返回函数letnavigate=useNavigate()///获取搜索字段letlocation=useLocation()return( 笔记详情 这是我于{params.itemId}记录的笔记,内容为{content}{deleteTodoItem(params.itemId)navigate('/Tab2/'+location.search)}}>删除笔记)}//src/data.jsxexportfunctiondeleteTodoItem(params){dataList=dataList.filter((value)=>value.id!==parseInt(params))}参考资料https://reactrouter.com/docs/en/v6/getting-started/tutorial
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 12:16 , Processed in 0.470588 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表