文章目录
路由的参数传递
传递参数有二种方式(需要注意的是, 这两种方式在Router6.x中都是提供的hook函数的API, 类组件需要通过高阶组件的方式使用):
动态路由的方式;
search传递参数(查询字符串);
方式一: 动态路由的概念指的是路由中的路径并不会固定:
比如/detail的path对应一个组件Detail;
如果我们将path在Route匹配时写成/detail/:id,那么 /detail/111、/detail/123都可以匹配到该Route,并且进行显示;
这个匹配规则,我们就称之为动态路由;
通常情况下,使用动态路由可以为路由传递参数。
- 配置动态路由
render(){return(<div className='app'><div className='header'><Link to="detail/123">详情123</Link><Link to="detail/321">详情321</Link><Link to="detail/aaa">详情aaa</Link></div><div className='counter'><Routes><Route path='/detail/:id' element={<Detail/>}/></Routes></div><div className='footer'>footer</div></div>)}
- 在跳转的页面中可以通过hook函数useParms获取到传入的id, 由于我们现在使用的是类组件, 无法使用hook函数, 因此需要通过高阶组件对当前组件增强(上一篇刚刚讲过高阶组件的封装, 这里直接使用, 给到大家代码)
import{ useNavigate, useParams }from"react-router-dom"exportdefaultfunctionwithRouter(WrapperComponent){returnfunction(props){const naviagte =useNavigate()const params =useParams()const router ={naviagte, params}return<WrapperComponent {...props} router={router}/>}}
- 使用高阶组件增强当前Detail组件, 就可以通过useParams获取到传递的id
import React,{ PureComponent }from'react'import withRouter from'../hoc/with_router'exportclassDetailextendsPureComponent{render(){// 获取到paramsconst{ params }=this.props.router
return(<div><h2>Detail</h2>{/* 通过params获取到id并展示 */}<h2>id:{params.id}</h2></div>)}}exportdefaultwithRouter(Detail)
方式二: search传递参数(也就是查询字符串的方式), 这里在User组件中进行演示
- 在路由跳转时拼接上查询字符串
render(){return(<div className='app'><div className='header'><Link to="/user?name=chenyq&age=18&height=1.88">用户</Link></div><div className='counter'><Routes><Route path='/user' element={<User/>}/></Routes></div><div className='footer'>footer</div></div>)}
- 查询字符串需要通过hook函数useSearchParams获取, 所以我们也需要使用高阶组件对User组件进行增强
// 封装的高阶组件import{ useNavigate, useParams, useSearchParams }from"react-router-dom"exportdefaultfunctionwithRouter(WrapperComponent){returnfunction(props){// 1.导航const naviagte =useNavigate()// 2.动态路由的参数const params =useParams()// 3.查询字符串的参数const[searchParams]=useSearchParams()const query = Object.fromEntries(searchParams.entries)const router ={naviagte, params, query}return<WrapperComponent {...props} router={router}/>}}
- 在组件中就可以获取到参数
import React,{ PureComponent }from'react'import withRouter from'../hoc/with_router'exportclassUserextendsPureComponent{render(){// 获取高阶组件中的queryconst{ query }=this.props.router
return(<div><h2>User</h2>{/* 通过query获取参数 */}<h2>参数:{query.name}-{query.age}-{query.height}</h2></div>)}}exportdefaultwithRouter(User)
路由的配置文件
目前我们所有的路由定义都是直接使用Route组件,并且添加属性来完成的。
但是这样的方式会让路由变得非常混乱,我们希望像vue-router那样, 将所有的路由配置放到一个单独的文件进行集中管理:
在早期的时候,Router并且没有提供相关的API,我们需要借助于react-router-config完成;
在Router6.x中,为我们提供了useRoutes API可以完成相关的配置;
例如我们将下面的映射关系配置到一个单独的文件中
<div className='counter'><Routes>{/* 当默认路径 / 时, 重定向到home页面 */}<Route path='/' element={<Navigate to="/home"/>}></Route>{/* 配置二级路由 */}<Route path='/home' element={<Home/>}><Route path='/home' element={<Navigate to="/home/recommend"/>}/><Route path='/home/recommend' element={<HomeRecommend/>}/><Route path='home/ranking' element={<HomeRanking/>}/></Route><Route path='/about' element={<About/>}/><Route path='/profile' element={<Profile/>}/><Route path='/category' element={<Category/>}/><Route path='/order' element={<Order/>}/><Route path='/detail/:id' element={<Detail/>}/><Route path='/user' element={<User/>}/>{/* 当上面路径都没有匹配到时, 显式Notfound组件 */}<Route path='*' element={<Notfound/>}/></Routes></div>
首先, 使用useRoutes这个API替代原来的Routes和Route组件, useRoutes可以当成一个函数直接使用, 但是只能在函数组件中使用
<div className='counter'>{useRoutes(routes)}</div>
再在route/index.js中对映射关系进行配置
import{ Navigate }from"react-router-dom"import Home from'../pages/Home'import About from'../pages/About'import Profile from'../pages/Profile'import Notfound from'../pages/Notfound'import HomeRecommend from'../pages/HomeRecommend'import HomeRanking from'../pages/HomeRanking'import Category from'../pages/Category'import Order from'../pages/Order'import Detail from'../pages/Detail'import User from'../pages/User'const routes =[{path:"/",element:<Navigate to="/home"/>},{path:"/home",element:<Home/>,children:[{path:"/home",element:<Navigate to="/home/recommend"/>},{path:"/home/recommend",element:<HomeRecommend/>},{path:"/home/ranking",element:<HomeRanking/>}]},{path:"/about",element:<About/>},{path:"/profile",element:<Profile/>},{path:"/category",element:<Category/>},{path:"/order",element:<Order/>},{path:"detail/:id",element:<Detail/>},{path:"/user",element:<User/>},{path:"*",element:<Notfound/>}]exportdefault routes
如果我们对某些组件进行了异步加载(懒加载, 分包处理),那么需要使用Suspense进行包裹:
例如我们对Detail和User进行懒加载(分包处理)
// import Detail from '../pages/Detail'// import User from '../pages/User'const Detail = React.lazy(()=>import("../pages/Detail"))const User = React.lazy(()=>import("../pages/User"))
并且还需要使用Suspense对组件进行包裹
root.render(<HashRouter><Suspense fallback={<h3>loading</h3>}><App/></Suspense></HashRouter>)
版权归原作者 蓝桉cyq 所有, 如有侵权,请联系我们删除。