经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » React » 查看文章
React-Router6版本的更新引起的路由用法变化
来源:jb51  时间:2022/1/18 17:31:55  对本文有异议

React Router应该是React生态系统中最受欢迎的库了,npm周下载量达600w+,github也有45.2k的加星,足以说明它是一款非常优秀的库,作为React社区重要的库,它经历了多次迭代和重大更改,就在上个月,更是迎来了一个大的正式版更新6.x,当前最新为6.0.2,相对比于之前的5.x版本做出了较大改变,不管从用法还是从性能上都有了明显的提升,本文也将用新老版本对比的方式让你能以最快的速度上手新用法

话不多说,先列出6.0做出的改变之处:

  1. 用法变化
  2. 替换为
  3. 嵌套路由新写法
  4. 推出全新hook,全面拥抱函数组件
  5. 基于对象的路由,实现js配置所有路由
  6. 整体代码比上个版本减小大约70%

用法变化

组件变化较大,移除了component与render属性,使用element属性替代,因为与之前的版本代码写法不能兼容,写法区别如下 

  1. ?// 5.x用法
  2. ? ?<Route path="/home" component={Home} />
  3. ? ?<Route path="/login" render={()=><Login/>}/>
  4.  
  5. ? ?// 6.x用法
  6. ? ?<Route path="/home" element={<Home/>} />
  7. ? ?<Route path="/login" component={<Login/>} />

替换为

v6版本移除了 组件,并使用替换,除了能替代 组件的功能外,也做了一些改变,比如所有的都必须包裹在中,否则抛出错误

  1. ?// 5.x用法
  2. ? ?<Switch>
  3. ? ? ? ?<Route path="/home" component={Home} />
  4. ? ? ? ?<Route path="/login" component={Login} />
  5. ? ?</Switch>
  6.  
  7. ? ?// 6.x用法
  8. ? ? <Routes>
  9. ? ? ? ?<Route path="/home" element={<Home/>} />
  10. ? ? ? ?<Route path="/login" component={<Login/>} />
  11. ? ?</Routes>

嵌套路由

v6版本的react-router支持多种嵌套路由写法,写法分别如下:

第一种写法:延续v5版本写法,保持原有组件结构 这种写法比较适合重构的项目,不需要改变太多的代码便能过渡到v6版本

  1. ? // App.jsx
  2. ? ?<Routes>
  3. ? ? ? ?<Route path="/home" element={<Home/>} />
  4. ? ? ? ?<Route path="/user/*" element={<User/>} />
  5. ? ?</Routes>
  6.  
  7. ? ?// User.jsx
  8. ? ?<Routes>
  9. ? ? ? ?<Route path="profile" element={<UserProfile/>} />
  10. ? ? ? ?<Route path=":/id" element={<UserDetail/>} />
  11. ? ?</Routes>

虽然组件结构与v5版本一至,但写法上有一定的差异,父组件App.jsx中的path属性最后必须使用星号(path="/user/*"),子组件User.jsx中的路径都是相对于其父级路径,所以不需要像v5版本那样写全整个路径,妈妈再也不用担心我会写错地址。

另外,如果中的path属性不以/开头,则是相对于其父级路径,这样的好处是使嵌套路由实现变得更加简单,并易于组合复杂的路由和布局

第二种写法:把所有的写在一起,配合实现路由组件的显示

  1. ?// App.jsx
  2. ? ?<Routes>
  3. ? ? ? ?<Route path="/home" element={<Home/>} />
  4. ? ? ? ?<Route path="/user" element={<User/>}>
  5. ? ? ? ? ? ?<Route path="profile" element={<UserProfile/>} />
  6. ? ? ? ? ? ?<Route path=":/id" element={<UserDetail/>} />
  7. ? ? ? ?</Route>
  8. ? ?</Routes>
  9.  
  10. ? ?// User.jsx
  11. ? ?<Outlet/>

这样写法让我们能更清晰地去了解路由结构,能更好地管理我们的路由,而能让我们能更精确地把嵌套的路由组件布局到需要位置显示

第三种写法:使用useRoutes()实现路由配置

使用useRoutes配置路由与配置路由效果一致,只是这种写法使用javascript生成路由,不依赖JSX,返回相应结构的路由组件树,有木有感觉回到了VueRouter?有木有?

  1. function App(){
  2. // 以下写法与第二种写法效果一至
  3. const element = useRoutes([
  4. {path:'/home',element:<Home/>},
  5. {
  6. path:'/user',
  7. element:<User/>,
  8. children:[
  9. {path:'profile',element:<UserProfile/>},
  10. {path:':/id',element:<UserDetail/>},
  11. ]
  12. }
  13. ])
  14. return element
  15. }

以上三种写法各有各的优点,开发者可以根据自身的需求选择一种来实现你的嵌套路由

重定向

新版本的react-router移除了组件,但可以使用新增的组件配合组件实现重定向效果

  1. <Routes>
  2. ? ? ? ?<Route path="/home" element={<Home/>} />
  3. ? ? ? ?<Route path="/" element={<Navigate to="/home"/>}>
  4. ? ?</Routes>

路由跳转

路由配置好后免不了要进行页面跳转,但新版的react-router移除了history对象,故不能使用v5版本的history(包括useHistory hook)已不能使用,我们可以使用以下两中方式进行跳转

使用或进行跳转这种方式与上一个版本几乎没有太大的区别,唯一的区别是组件的高亮写法发生了变化

  1. // v5版本
  2. <NavLink to="/home" activeStyle={{color:'#f00'}}>首页</NavLink>
  3. <NavLink to="/home" activeClassName="active">首页</NavLink>
  4.  
  5. // v6版本
  6. <NavLink to="/home" style={({isActive})=>(isActive?{color:'#f00'}:{})}>首页</NavLink>
  7. <NavLink to="/home" className={({isActive})=>isActive?'current':''}>首页</NavLink>

PS: 默认已经有一个高亮的active类,可以直接使用,不需要额外设置
使用useNavigate()进行跳转有时候我们并不能使用以上两个组件进行跳转,如根据ajax请求返回值跳转不同的页面,这时我们就得使用js的方式时行跳转了,虽然新版的react-router已经移除掉history对象,但给我们提供了 useNavigate hook实现路由跳转,使用方法如下

  1. ?import { useNavigate } from "react-router-dom";
  2. ? ?let navigate = useNavigate();
  3. ? ?navigate(`/home`);
  4.  
  5. ? ?// 跳转且不保留浏览记录
  6. ? ?navigate(`/home`,{replace:true});
  7.  
  8. ? ?// 返回上一页
  9. ? ?navigate(-1)
  10.  
  11. ? ?// 对象方式跳转
  12. ? ?navigate({
  13. ? ? ? ?pathname:'/home'
  14. ? })

需要注意一点就是,在v6版本的react-router中,如果跳转的路径如果不是以/开头,则为相对路径,相对于其父级路由路径,这样的设置能让我们更好的控制跳转

路由传参

我们都知道,在进行路由跳转时,可以附带一些参数一起传递到跳转页面,新版的react-router已经从props中移除了history、location、match,也移除掉了withRouter高阶组件,所以无法使用老版本的方式传参与接收,新版用法如下

search传参

  1. ?let navigate = useNavigate();
  2. ? ?navigate(`/home?page=1&size=10`);
  3. ? ?navigate({
  4. ? ? ? ?pathname:'/home',
  5. ? ? ? ?search:'page=1&size=10'
  6. ? });

在对应组件接收参数也很简单,使用useSearchParams hook进行接收,得到URLSearchParams对象以及设置search参数函数组成的数据

  1. ? ?function Home(){
  2. ? ? ? ?const [searchParams,setSearchParams] = useSearchParams()
  3. ? ? ? ?searchParams.get('page');//1
  4. ? ? ? ?searchParams.get('size');//10
  5. ? ? ? ?return (
  6. ? ? ? ? ? ?<div>首页</div>
  7. ? ? ? )
  8. ? }

动态路由传参

  1. <Route path="/user" element={<User/>}>
  2. <Route path=":/id" element={<UserDetail/>} />
  3. </Route>

配置完以上路由后,当页面跳转到/user/123这个路径时,可以在组件中使用useParams hook获取123这个id

  1. function UserDetail(){
  2. const {id} = useParams()
  3. return (
  4. <div>id:{id}</div>
  5. )
  6. }

state传参通过、或 useNavigate进行跳转时,都可以传递state参数,用法如下:

  1. <Link to="/home" state={{idx:1,key:'qf'}}>首页</Link>
  2. navigate('/home',{state:{idx:1,key:'qf'}})

在首页组件中通过useLocation hook获取state值

  1. function Home(){
  2. const {state} = useLocation();
  3. state.idx; // 1
  4. state.key; // qf
  5. return (
  6. <div>首页</div>
  7. )
  8. }

其他

另外,React路由同样支持SSR服务端渲染等其它功能,由于篇幅在限,在此不做过多说明,感兴趣的小伙伴请继续关注我,后续的写文章专门介绍react-router在在服务端的用法。

总结

以上就是本文的所有内容,希望通过该文章能让大家对新版本react-router有个全面的认识,以便在项目中应用新版路由。更多相关React-Router6路由内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号