ReactReact全家桶React Router 6
Posted 前端More
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactReact全家桶React Router 6相关的知识,希望对你有一定的参考价值。
文章目录
1 React Router 6 概述
React Router 6以三个不同的包发布到 npm 上,它们分别为:
-
react-router
: 路由的核心库,提供了很多的组件、钩子。 -
react-router-dom
: 包含react-router所有内容,并添加一些专门用于 DOM 的组件,例如<BrowserRouter>
等。 -
react-router-native
: 包括react-router所有内容,并添加一些专门用于ReactNative的API,例如:<NativeRouter>
等。
与React Router 5.x 版本相比,改变了什么?
- 内置组件的变化:移除
<Switch/>
,新增<Routes/>
等。 - 语法的变化:
component=About
变为element=<About/>
等。 - 新增多个hooks:
useParams
、useNavigate
、useMatch
等。 - 官方明确推荐
函数式组件
说明:
- React Router 5重复的内容在本文中没有赘述,有兴趣的小伙伴可以看下【React】React全家桶(七)路由简介与React Router 5
- React Router 6官方文档
2 Component组件
2.1 router组件(BrowserRouter 、 HashRouter)
基于React Router的web应用,根组件应该是一个router组件(BrowserRouter、HashRouter),<BrowserRouter>
和HashRouter
就是router根组件,用于包裹整个应用。<HashRouter>
作用与<BrowserRouter>
一样,但<HashRouter>
修改的是地址栏的hash值。
< BrowserRouter
// 所有路由的基础地址
basename = optionalString
// 如果设置为true,路由router将会在跳转的时候进行整个页面刷新
forceRefresh = optionalBool
// 用来确认是否跳转,默认使用window.confirm
getUserConfirmation = optionalFunc
// location.key的长度,默认为6
keyLength = optionalNumber
>
</ BrowserRouter >
备注
:6.x版本中<HashRouter>
、<BrowserRouter>
的用法与 5.x 相同。
示例代码
import React from "react";
import ReactDOM from "react-dom";
import BrowserRouter from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
/* 整体结构(通常为App组件) */
<App/>
</BrowserRouter>,root
);
2.2 路由匹配组件(Routes 、 Route)
-
v6版本中移出了先前的
<Switch>
,引入了新的替代者
:<Routes>
。 -
<Routes>
和<Route>
要配合使用,且必须要用<Routes>
包裹<Route>
,<Routes>
会迭代它下面的所有<Route>
子组件,并只渲染第一个路径匹配的
,这样只要匹配到了第一个就不会再往下匹配了。当URL发生变化时,<Routes>
都会查看其所有子<Route>
元素以找到最佳匹配并呈现组件 。 -
<Routes>
和<Route>
可由useRoutes()
配置 “路由表”生成路由代替 -
路由匹配
是通过将<Route>组件的path属性
与当前的location的pathname
进行比较来完成的。 当一个<Route>
匹配了 ,它所对应的组件内容将被渲染出来。 -
<Route caseSensitive>
属性用于指定匹配时是否区分大小写,增加caseSensitive就区分大小写。 -
<Route>
也可以嵌套使用,但需要通过<Outlet>
组件来渲染其子路由。
示例代码
<Routes>
/*path属性用于定义路径,element属性用于定义当前路径所对应的组件*/
<Route path="/login" element=<Login />></Route>
/*用于定义嵌套路由,home是一级路由,对应的路径/home*/
<Route path="home" element=<Home />>
/*test1 和 test2 是二级路由,对应的路径是/home/test1 或 /home/test2*/
<Route path="test1" element=<Test/>></Route>
<Route path="test2" element=<Test2/>></Route>
</Route>
//Route也可以不写element属性, 这时就是用于展示嵌套的路由 .所对应的路径是/users/xxx
<Route path="users">
<Route path="xxx" element=<Demo /> />
</Route>
</Routes>
2.3 Navigation组件(Link、NavLink、Navigate)
Link
-
作用
: 修改URL,且不发送网络请求(路由链接)。 -
注意
: 外侧需要用<BrowserRouter>
或<HashRouter>
包裹。
示例代码
import Link from "react-router-dom";
function Test()
return (
<div>
<Link to="/路径">按钮</Link>
</div>
);
NavLink
作用
: 与<Link>
组件类似,且可实现导航的“高亮”效果。
示例代码
// 注意: NavLink默认类名是active,下面是指定自定义的class
//自定义样式
<NavLink
to="login"
className=( isActive ) =>
console.log('home', isActive)
return isActive ? 'base one' : 'base'
>login
</NavLink>
/*
默认情况下,当Home的子组件匹配成功,Home的导航也会高亮,
当NavLink上添加了end属性后,若Home的子组件匹配成功,则Home的导航没有高亮效果。
*/
<NavLink to="home" end >home</NavLink>
Navigate
作用
:只要<Navigate>
组件被渲染,就会修改路径,切换视图。- push模式(默认):可以留下操作记录,不发生替换
- replace模式:开启的路由不会留下操作记录,发生替换
示例代码
import React,useState from 'react'
import Navigate from 'react-router-dom'
export default function Home()
const [sum,setSum] = useState(1)
return (
<div>
<h3>我是Home的内容</h3>
/* 根据sum的值决定是否切换视图 */
sum === 1 ? <h4>sum的值为sum</h4> : <Navigate to="/about" replace />
<button onClick=()=>setSum(2)>点我将sum变为2</button>
</div>
)
2.4 Outlet
作用
:当<Route>
产生嵌套时,渲染其对应的后续子路由。
示例代码
routes/index.js
//路由表
import About from '../pages/About'
import Home from '../pages/Home'
import Navigate from 'react-router-dom'
export default [
path:'/about',
element:<About/>
,
path:'/home',
element:<Home/>,
children:[
path:'news',
element:<News/>
,
path:'message',
element:<Message/>
]
,
path:'/',
element:<Navigate to="/about"/>
]
pages/Home.jsx
import React from 'react';
import NavLink, Outlet from 'react-router-dom';
export default function Home()
return (
<div>
<h2>Home组件内容</h2>
<div>
<ul className="nav nav-tabs">
<li>
<NavLink className="list-group-item" to="news">
News
</NavLink>
</li>
<li>
<NavLink className="list-group-item" to="message">
Message
</NavLink>
</li>
</ul>
/* 指定Home组件下子路由组件的呈现位置 */
<Outlet />
</div>
</div>
);
3 Hooks
3.1 useRoutes()
作用
:根据路由表,动态创建路由<Routes>
和<Route>
。
示例代码
routes/index.js
//路由表
import About from '../pages/About'
import Home from '../pages/Home'
import Navigate from 'react-router-dom'
export default [
path:'/about',
element:<About/>
,
path:'/home',
element:<Home/>
,
path:'/',
element:<Navigate to="/about"/>
]
App.jsx
import React from 'react'
import NavLink,useRoutes from 'react-router-dom'
import routes from './routes'
export default function App()
//根据路由表生成对应的路由规则
const element = useRoutes(routes)
return (
<div>
/* 注册路由 */
element
</div>
)
/* element 等于下面的路由解构*/
<Routes>
<Route path="/about" element=<About/>></Route>
<Route path="/home" element=<Home/>></Route>
/* v6的Navigate替换了Redirect */
<Route path="/" element=<Navigate to="/about" />></Route>
</Routes>
3.2 useParams()
作用
:获取当前匹配路由的params
参数,类似于5.x中的match.params
。
向路由组件传递params参数:
- 路由链接(携带参数):
<Link to='/demo/test/tom/18'>详情</Link>
- 注册路由(声明接收):
<Route path="/demo/test/:name/:age" element=<Test/> />
- 接收参数:
const name,age =useParams()
示例代码
routes/index.js
import Home from '../pages/Home';
import Message from '../pages/Message';
import Detail from '../pages/Detail';
import Navigate from 'react-router-dom';
export default [
path: '/home',
element: <Home />,
children: [
path: 'message',
element: <Message />,
children: [
path: 'detail/:id/:title/:content',
element: <Detail />,
,
],
,
],
,
path: '/',
element: <Navigate to="/about" />,
,
];
pages/Message.jsx
import React, useState from 'react';
import Link, Outlet from 'react-router-dom';
export default function Message()
const [messages] = useState([
id: '001', title: '消息1', content: '锄禾日当午' ,
id: '002', title: '消息2', content: '汗滴禾下土' ,
id: '003', title: '消息3', content: '谁知盘中餐' ,
id: '004', title: '消息4', content: '粒粒皆辛苦' ,
]);
return (
<div>
<ul>
messages.map(m =>
return (
// 路由链接
<li key=m.id>
<Link to=`detail/$m.id/$m.title/$m.content`>m.title</Link>
</li>
);
)
</ul>
<hr />
/* 指定路由组件的展示位置 */
<Outlet />
</div>
);
pages/Detail.jsx
import React from 'react'
import useParams,useMatch from 'react-router-dom'
export default function Detail()
const id,title,content = useParams()
//此处还可以使用useMatch() 返回当前匹配信息,对标5.x中的路由组件的`match`属性。
// const x = useMatch('/home/message/detail/:id/:title/:content')
return (
<ul>
<li>消息编号:id</li>
<li>消息标题:title</li>
<li>消息内容:content</li>
</ul>
)
3.3 useMatch()
作用
:返回当前匹配信息,对标5.x中的路由组件的match
属性。
示例代码
<Route path="/login/:page/:pageSize" element=<Login />/>
<NavLink to="/login/1/10">登录</NavLink>
export default function Login()
const match = useMatch('/login/:x/:y')
console.log(match) //输出match对象
//match对象内容如下:
/*
params: x: '1', y: '10'
pathname: "/LoGin/1/10"
pathnameBase: "/LoGin/1/10"
pattern:
path: '/login/:x/:y',
caseSensitive: false,
end: false
*/
return (
<div>
<h1>Login</h1>
</div>
)
3.4 useSearchParams()
作用
:用于读取和修改当前位置的 URL 中的查询字符串。获取当前匹配路由的search参数
,类似于5.x中的location.search
。
向路由组件传递search参数:
-
路由链接(携带参数):
<Link to='/demo/test?name=tom&age=18'>详情</Link>
-
注册路由(无需声明,正常注册即可):
<Route path="/demo/test" element=<Test/>/>
-
接收参数:
//useSearchParams返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数。 const search,setSearch =useSearchParams() const name =search.get('name') const id =search.get('id')
示例代码
routes/index.js
import Home from '../pages/Home';
import Message from '../pages/Message';
import Detail from '../pages/Detail';
import Navigate from 'react-router-dom';
export default [
path: '/home',
element: <Home />,
children: [
path: 'message',
element: <Message />,
children: [
path: 'detail/:id/:title/:content',
element: <Detail />,
,
],
,
],
,
path: '/',
element: <Navigate to="/about" />,
,
];
pages/Message.jsx
import React, useState from 'react';
import Link, Outlet from 'react-router-dom';
export default function Message()
const [messages] = useState([
id: '001', title: '消息1', content: '锄禾日当午' ,
id: '002', title: '消息2', content: '汗滴禾下土' ,
id: '003', title: '消息3', content: '谁知盘中餐' ,
id: '004', title: '消息4', content: '粒粒皆辛苦' ,
]);
return (
<div>
<ul>
messages.map(m =>
return (
// 路由链接
<li key=m.id>
<Link to=`detail?id=$m.id&title=$m.title&content=$m.content`> m.title
以上是关于ReactReact全家桶React Router 6的主要内容,如果未能解决你的问题,请参考以下文章