React router V6的基本使用
一:概述
React Router 由三个模块组成,分别是:
- react-router:路由的核心库,提供核心的组件和钩子。
- react-router-dom:基于react-router,并添加专门用于DOM的组件,例如:<BrowserRouter / >等。
- react-router-native:基于react-router,并添加专门用于ReactNative的API,例如:<NativeRouter / >等。
二:router Component
以下描述的是组件,通过使用组件的方式,渲染视图。
1. <BrowserRouter / > 与 <HashRouter / >
使用:在最外层包裹整个应用
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
// react-router-dom 是基于react-router,添加dom所需的Api,所有只需要react-router-dom
const root = ReactDOM.createRoot(document.getElementById("root"));
// BrowserRouter模式,访问地址:http://localhost:8080/home
// 类似vue的history模式
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
)
//hash模式,访问地址:http://locahost:8080/#/home
root.render(
<React.StrictMode>
<HashRouter>
<App />
</HashRouter>
</React.StrictMode>
)
两则对比:
- hash模式兼容好,history模式是html5提出的,兼容性差(移动端兼容性不错)
- hash模式下,访问不存在的页面,不需要单独配置nginx。而history模式需要。
- history模式路由更好看;hash模式带#号,不美观,而且处理描点链接不方便。
以下案例,默认history模式,并只展示核心代码段
2. <Routes / > 与 <Route / >
- <Route / >必须配合 <Routes / > 使用,被<Routes / >包裹,区别V5 的<Switch / >。
- <Route / > 相当与if 语句,当其路径与当前url匹配时,则呈现对应的组件。
- <Route / >可以嵌套使用,需要通过<Outlet / > 组件来渲染子路由;
import { Routes, Route } from "react-router-dom";
<Routes>
// 1. path 定义路径,element 定义对应渲染组件
<Route path="/" element={<Login />} />
<Route path="/layout" element={<WebLayout />}>
// 2. 嵌套路由需要<Outlet />组件配合使用,该路由访问路径http://localhost:8080/layout/main
<Route path="main" element={<Home />} />
</Route>
// 3. Route 也可以不写element属性,展示嵌套路由,对应路由是:/tab/list
<Route path="/tab">
<Route path="list" element={<List />} />
</Route>
// 4. Route 定义replace属性为true的时候,不会产生历史历史记录。默认是false
<Route path="/list" element={<List>} replace={true} />
// 5. Route 定义Index属性,不需要定义path属性,在子路由里显示该路由页面。
<Route path="/main" element={<Main />}>
<Route index element={<Test1 />} />
// 6. 定义动态的路由,访问地址:http://localhost:8080/1
<Route path=":id" element={<Test2 />} />
// 访问路径:http://localhost:8080/main/list/1
<Route path="list/:id" element={<Test2 />} />
</Route>
</Routes>
3. <Link / > 与 <NavLink / >
必须被<BrowserRouter / > 或 <HashRouter / > 包裹
- < Link / >类似a标签的,单区别于a标签,是基于a标签封装的组件。 最终<Link / >组件会转为a标签。通常的应用场景类似a标签,不同页面之间的跳转。
- 有三种传参方式,1. params 2. searchParams 3. state
import { Link } from "react-router-dom";
// to的路由是对象,属性pathName。定义三种传参方式如下:
<Link to={{ pathName: "/" }}></Link>
// params传参 /detail/:id
<Link to="/detail/1"><Link>
<Link to=`/detail/${id}`><Link>
// searchParams传参 /detail?id=1
<Link to="/detail?id=1"></Link>
<Link to=`/detail?id=${id}`></Link>
// state 传参
<Link to="/" state={{ id: 1 }}>
// replace 为true的时候,不产生历史记录, 默认replace={false}
< Link to="/detail" replace={ true }>
- <NavLink / > 组件和<Link / > 组件使用一致。是激活版的 <Link / >组件,可以实现导航的“高亮”效果。通常的使用场景是在同一个界面,tab栏切换,导航高亮,展示对应。
import { NavLink } from "react-router-dom";
// NavLink 组件的class 会返回含有isActive的对象,为true的时间,改导航路由被激活。
<NavLink to="/go" className={({ isActive }) => {
return isActive ? "red" : "blue"
}}> go </NavLink>
4. <Navigate / >
- <Navigate / > 组件被渲染,路径被修改,切换视图。
- 可以定义replace属性,来控制跳转模式(模式是push, 会产生历史记录)
import { Navigate } from "react-router-dom";
<Navigate to="/" />
<Navigate to="/" replace={true} />
5. <Outlet / >
- 当route 发生嵌套的时候,必须使用<Outlet / >组件来渲染子路由对应的视图。 类似 props.children, 或者 vue-router中的 <router-veiw / >,子路由渲染组件占位符。
import { Routes, Route, Outlet } from "react-router-dom";
function Module() {
return (
<div>
<h2>我是Modules组件</h2>
// 如果不写 <Outlet /> 组件,<Item /> 视图是渲染不出来的。
<Outlet />
</div>
)
}
function Item() {
return (
<div>
<h2>我是Item组件</h2>
</div>
)
}
function App() {
return (
<Routes>
<Route to="/tab" element={ <Module /> }>
<Route to="item" element={ <Item /> }>
</Route>
</Routes>
)
}
- <Route to=“” element={ } replace={ true } />
- < Link to=“” replace={true} / >
- <Navigate to=“/” replace={true} / >
组件定义replace 的三种方式。
三:router hooks
以下通过js调用,实现像组件形式的路由,获取参数,重定向等。
1. useRoutes()
- 接收数组生成路由表,动态创建Routes 和 Route。 类似vue-router, 通过js配置路由;
// router.jsx
// 这里也可以定义纯js,定义router.js配置路由,类似vue中那样配置路由。
import React from "React"
import { useRoutes, Navigate } from "react-router-dom"
import Home from "../views/home.jsx";
import Loading from "./components/loading.jsx";
// 利用React.lazy 懒加载组件
const List = React.lazy(() => import("../views/list.jsx"))
// 懒加载组件
function lazyComponent(path) {
const Comp = React.lazy(() => import(`../views/${path}`));
return (
// fallcack 可自定义全局<Loading />组件,在切换页面或模块显示loading过程,提高用户体验。
<React.Suspense fallback={ <Loading title="加载中..." /> }>
<Comp />
</React.Suspense>
)
}
const routes = [
{
path: "/",
element: <Home />
},
{
path: "/list",
element: <List />
},
{
path: "/detail",
element: lazyComponent("detail.jsx")
},
{
path: "/",
element: <Navigate to="/login" />
}
]
export const RouteList = () => {
const router = useRoutes(routes);
return <> { router } </>
}
// App.js
import { RouteList } from "./router.jsx"
function App(){
return <RouteList />
}
2. useNavigate()
通过useNavigate()返回的参数navigate是一个函数
- 第一个参数是路径
- 第二个参数为option配置对象
import { useNavigate } from "react-router-dom"
export const Demo = () => {
const navigate = useNavigate();
const handle = () => {
navigate("/login", {
replace: true,
state: {
name: "error"
}
})
// 上述是state传参,params 和 searchParmas 传参的话, 需要手动拼接
// - params
navigate(`/detail/${id}`);
// - searchParmas
navigate(`/detail?name=${name}&age=${age}`);
}
return (
<div>
// 类似history.go(-1)
<button onClick={() => navigate(-1)}>后退</button>
// 类似history.go(1)
<button onClick={() => navigate(1)}>前进</button>
<button onClick={handle}>按钮</button>
</div>
)
}
3. useParams()
- 匹配路由的params参数
// App.js
import { Routes, Route } from "react-router-dom"
<Routes>
<Route to="/list/:id" element={<Detail />} />
</Routes>
// 访问路由http://localhost:8080/list/1
// detail.jsx
import { useParams } from "react-router-dom"
export const Detail = () => {
// 获取URL中携带过来的params参数
const { id } = useParams(); // id = 1
return <div>detail</div>
}
4. useSearchParams()
- 读取和修改当前位置的 URL 中的查询字符串
- 返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数
// App.js
import { useSearchParams } from "react-router-dom"
<Routes>
<Route to="/list?name=wei&age=18" element={<Detail />} />
</Routes>
// 访问路由http://localhost:8080/list/1
// detail.jsx
import { useSearchParams } from "react-router-dom"
export const Detail = () => {
// 获取URL中携带过来的searchParams参数
const [search,setSearch] = useSearchParams();
const name = search.get("name"); // wei
const age = search.get("age"); // 18
// 点击,url变成http://localhost:3000/detail?name=zhang&age=19
return <div onClick={() => setSearch("name=zhang&age=19")}>设置urlParams</div>
}
5. useLocation()
- 获取当前 location 信息,对标5.x中的路由组件的location属性
- 使用state进行传参,对useLocation返回的对象进行解构赋值即可,同时不需要占位
import { useLocation } from "react-router-dom"
export const Detail = () => {
const location = useLocation();
console.log(location) // 打印内容如下:
/*
{
hash: "",
key: "ahn9u7sh",
pathname: "/list",
search: "?name=wei&age=18",
state: {a: 1, b: 2}
*/
}
6. useMatch()
- 返回当前匹配的信息,需要传入匹配的路由(不传会报错)
import { Route, Link, useMatch } from "react-router-dom"
<Route to="/test1" element={<Home />}></Route>
// Home
<Link to="/test1"></Link>
export default function Home() {
// const match = useMatch(); // 报错
// const match = useMatch(""); // 不会报错
const match = useMatch("/test1")
console.log(match);
/*
{
// 对应params参数
params: {}
pathname: "/test1"
pathnameBase: "/test1"
// 如果配置的路由是:/detail/:id, 这里的pattern 展示的就是/detail/:id
pattern:
caseSensitive: false
end: true
path: "/test1"
}
*/
}
7. useInRouterContext()
- 是否处于路由上下文环境 返回boolean
import { useInRouterContext } from "react-router-dom"
function App(){
const Context = useInRouterContext();
console.log(Context); // true
return <div>App</div>
}
function Demo(){
const Context = useInRouterContext();
console.log(Context); // false
return <div>Demo</div>
}
ReactDOM.render(
// App组件被路由组件包裹,而Demo组件没有被包裹
<div>
<Demo />
<BrowserRouter >
<App />
</BrowserRouter>
</div>
, document.getElementById('root'))
8. useNavigationType()
- 返回用户的导航类型,用户是怎么进入当前页面的,包含有:POP, PUSH, REPLACE
- 返回的三种类型都是大写。
- pop 是根据url直接在浏览器打开。
import { useNavigationType, Outlet } from "react-router-dom"
export default function Home(){
const navigationType = useNavigationType();
console.log(navigationType); // 返回值:POP, PUSH, REPLACE
return <><Outlet /></>
}
9. useOutlet()
- 在嵌套路由中使用,父组件使用<Outlet / >, 当子组件渲染的时候,会展示嵌套路由的对象。如果嵌套路由没有挂载,返回是null。
import { useOutlet, Link, Outlet, Routes, Route } from "react-router-dom"
function Home(){
const outlet = useOutlet();
//当访问:http://localhost:8080/
console.log(outlet); // null
// 当访问:http://locahost:8080/main
console.dir(outlet);
/*
$$typeof: Symbol(react.element)
key: null
props: {value: undefined, children: {…}}
ref: null
type: {$$typeof: Symbol(react.provider), _context: {…}}
_owner: FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
_store: {validated: false}
_self: null
_source: null
*/
return (
<>
<h2>Home</h2>
<Link to="/main">go</Link>
<Outlet />
</>
);
}
function Main() {
return <div>main</div>;
}
<Routes>
<Route path="/" element={<Home />}>
<Route path="/main" element={<Main />} />
</Route>
</Routes>
10. useResolvedPath()
- 用来解析url值,返回一个对象,对象包含有hash,pathname,search 三个属性。
import { useResolvedPath } form "react-router-dom"
export default function Home() {
// 注意:detail的 “/” 不要忘了,否则会拼接地址栏的url
const pathObj = useResolvedPath("/detail?name=wei&age=18");
console.log(pathObj);
/*
{
hash: ""
pathname: "/detail"
search: "?name=wei&age=18"
}
*/
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfheeb
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13