React Router 6
1.<BrowserRouter>
1.说明:<BrowserRouter>用于包裹整个应用.
2.示例代码:
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
{/_ 整体结构 (通常为 App 组件) _/}
</BrowserRouter>,
root)
2.<HashRouter>
1. 说明: 作用与<BrowserRouter>一样,但<HashRouter>修改的是地址栏的 hash 值.
2. 备注: 6.x 版本中<HashRouter><BrowserRouter>的用法与 5.x 相同
3.<Routes/> 与 <Route/>
1.v6 版本中移出了先前的<Switch>,引入了新的替代者: <Routes>.
2.<Routes>和 <Route>要配合使用,且必须要用<Routes>包裹<Route>.
3.<Route>相当于一个 if 语句,如果其路径与当前 URL 匹配,则呈现其对应的组件
4.<Route caseSensitive> 属性用于指定: 匹配时是否区分大小写 (默认为 false).
5.当 URL 发生变化时,<Routes>都会查看其所有子<Route> 元素以找到最佳匹配并呈现组件
6.<Route>也可以嵌套使用,且可配合 useRoutes() 配置"路由表",但需要通过<outlet>组件来渲染其子路由.
7. 示例代码
<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>
4. <Link>
1.作用: 修改URL,且不发送网络请求 (路由链接)
2.注意:外侧需要用<BrowserRouter>或<HashRouter>包裹
3. 示例代码:
import { Link } from "react-router-dom";
function Test() {
return (
<div>
<Link to="/路径">按钮</Link>
</div>
)
}
5. <NavLink>
1.作用: 与<Link>组件类似,且可实现导航的"高亮"效果
2. 示例代码:
// 注意: 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>
6. <Navigate>
1.作用:只要<Navigate>组件被染,就会修改路径,切换视图.
2.replace 属性用于控制跳转模式 (push 或 replace,默认是push).
3.示例代码:
import React,fuseStater 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={true}/>}
<button onClick={()=>setSum(2)}>点我将sum变为2</button>
</div>
)
}
6. <Outlet>
1. useRoutes()
2. useNavigate()
3. useParams()
4. useSearchParams()
5. useLocation()
6. useMatch()
7. uselnRouterContext()
8. useNavigationType()
1.作用: 返回当前的导航类型 (用户是如何来到当前页面的)
2.返回值: POP、PUSH、REPLACE
3.备注: PoP 是指在浏览器中直接打开了这个路由组件 (刷新页面)
9. useOutlet()
1.作用: 用来呈现当前组件中渲染的嵌套路由
2.示例代码:
const result = useOutlet()
console.log(result)
10. useResolvedPath()
1.作用: 给定一个 URL值,解析其中的: path、search、hash值.
01-一级路由
import React, { Component } from "react";
import { NavLink, Route, Routes, Navigate, useRoutes } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
import routers from "./routers";
export default function App() {
return (
<div>
<h1>我是APP</h1>
{/* 注册跳转标签 */}
<NavLink to="/about">About</NavLink>
<NavLink to="/home">Home</NavLink>
{/* 注册路由 普通写法 */}
{/* 之前 Switch 现在是 Routes */}
<Routes>
{/* 之前是 Component 现在是 element */}
{/* 现在 path 是大小写都可以了 about ABOUT 是一样的 都会被解析成小写 */}
<Route path="/about" element={<About />} />
<Route path="/home" element={<Home />} />
{/* Routes 和之前一样,一个匹配上后就不会去匹配别的了 */}
<Route path="/home" element={<Demo />} />
</Routes>
</div>
);
}
02-Navigate 重定向
import React, { Component } from "react";
import { NavLink, Route, Routes, Navigate, useRoutes } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
export default function App() {
return (
<div>
<h1>我是APP</h1>
{/* 注册跳转标签 */}
<NavLink to="/about">About</NavLink>
<NavLink to="/home">Home</NavLink>
{/* 注册路由 普通写法 */}
{/* 之前 Switch 现在是 Routes */}
<Routes>
{/* 之前是 Component 现在是 element */}
{/* 现在 path 是大小写都可以了 about ABOUT 是一样的 都会被解析成小写 */}
<Route path="/about" element={<About />} />
<Route path="/home" element={<Home />} />
{/* Routes 和之前一样,一个匹配上后就不会去匹配别的了 */}
<Route path="/home" element={<Demo />} />
{/* Navigate 和之前的 redirect 效果一样,写法不一样 */}
<Route path="/" element={<Navigate to="/about" />} />
</Routes>
</div>
);
}
import React, { Component, useState } from "react";
import { Navigate } from "react-router-dom";
export default function Home() {
const [sum, setSum] = useState(0);
return (
<div style={{ padding: "10px" }}>
<div style={{ border: "1px solid red" }}>
<h2>导航区</h2>
<div>
<a style={{ float: "left", marginRight: "10px" }}>About</a>
<a style={{ color: "red" }}>Home</a>
</div>
</div>
<div style={{ border: "1px solid green", marginTop: "10px" }}>
<h2>展示区</h2>
<h2>Home</h2>
{/* 这样样式一个 Navigate 的使用方法 */}
{/* Navigate 只要渲染就会引起页面的切换 */}
{sum === 2 ? (
<Navigate to="/about" replace />
) : (
<h4>当前的sum的值为{sum}</h4>
)}
<button onClick={() => setSum(2)}>点击改变sum的值</button>
</div>
</div>
);
}
03-NavLink 高亮
import React, { Component } from "react";
import { NavLink, Route, Routes, Navigate, useRoutes } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
export default function App() {
return (
<div>
<h1>我是APP</h1>
{/* 注册跳转标签 */}
{/* 之前是 activeClassName 现在是 className 返回一个函数 */}
<NavLink
className={({ isActive }) => (isActive ? "lgqactive" : "aaa")}
to="/about"
>
About
</NavLink>
<NavLink
className={({ isActive }) => (isActive ? "lgqactive" : "aaa")}
to="/home"
>
Home
</NavLink>
{/* 注册路由 普通写法 */}
{/* 之前 Switch 现在是 Routes */}
<Routes>
{/* 之前是 Component 现在是 element */}
{/* 现在 path 是大小写都可以了 about ABOUT 是一样的 都会被解析成小写 */}
<Route path="/about" element={<About />} />
<Route path="/home" element={<Home />} />
</Routes>
</div>
);
}
04-useRoutes 路由表
04-useRoutes 路由表\App.jsx
import React, { Component } from "react";
import { NavLink, useRoutes } from "react-router-dom";
import routers from "./routers";
export default function App() {
const element = useRoutes(routers);
return (
<div>
<h1>我是APP</h1>
{/* 注册跳转标签 */}
{/* 之前是 activeClassName 现在是 className 返回一个函数 */}
<NavLink to="/about">About</NavLink>
<NavLink to="/home">Home</NavLink>
{/* 路由表写法 */}
{element}
</div>
);
}
04-useRoutes 路由表\routers\index.js
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
export default [
{
path: "/about",
element: <About />,
},
{
path: "/home",
element: <Home />,
},
{
path: "/",
element: <Navigate to="/about" />,
},
];
05-Outlet 组件展示位置
import React, { Component, useState } from "react";
import { NavLink, Outlet } from "react-router-dom";
export default function Home() {
return (
<div style={{ padding: "10px" }}>
<div style={{ border: "1px solid red" }}>
<h2>导航区</h2>
<div>
<a style={{ float: "left", marginRight: "10px" }}>About</a>
<a style={{ color: "red" }}>Home</a>
</div>
</div>
<div style={{ border: "1px solid green", marginTop: "10px" }}>
<h2>展示区</h2>
<h2>Home</h2>
<NavLink
to="message"
className={({ isActive }) => (isActive ? "lgqactive" : "")}
>
Message
</NavLink>
<NavLink
to="news"
className={({ isActive }) => (isActive ? "lgqactive" : "")}
>
News
</NavLink>
{/* 指定路由组件呈现的位置, 类似Vue的 route-view */}
<Outlet />
</div>
</div>
);
}
06-路由的 params 参数
06-路由的 params 参数\routers\index.js
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
import Message from "../pages/Home/Message";
import News from "../pages/Home/News";
import Detail from "../pages/Home/Message/Detail";
export default [
{
path: "/about",
element: <About />,
},
{
path: "/home",
element: <Home />,
children: [
{
path: "message",
element: <Message />,
children: [
{
path: "detail/:id/:title/:content",
element: <Detail />,
},
],
},
{
path: "news",
element: <News />,
},
],
},
{
path: "/",
element: <Navigate to="/about" />,
},
];
06-路由的 params 参数\pages\Home\Message\index.jsx
import React, { Component, useState } from "react";
import { Link, NavLink, Outlet } from "react-router-dom";
export default function Message() {
const [message] = useState([
{ id: 1, title: "消息1", content: "内容1" },
{ id: 2, title: "消息2", content: "内容2" },
{ id: 3, title: "消息3", content: "内容3" },
{ id: 4, title: "消息4", content: "内容4" },
]);
return (
<div>
<ul>
{message.map((el) => {
return (
<li key={el.id}>
{/* 路由 params 参数 */}
<Link to={`detail/${el.id}/${el.title}/${el.content}`}>
{el.title}
</Link>
</li>
);
})}
</ul>
<hr />
{/* 指定 Detail 的展示位置 */}
<Outlet />
</div>
);
}
06-路由的 params 参数\pages\Home\Message\Detail\index.jsx
import React from "react";
import { useParams } from "react-router-dom";
export default function Detail() {
const { id, title, content } = useParams();
const _history = useMatch("/home/message/detail/:id/:title/:content");
return (
<div>
<span>{id}</span> -<span>{title}</span> -<span>{content}</span>
</div>
);
}
07-路由的 search 参数
07-路由的 search 参数\routers\index.js
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
import Message from "../pages/Home/Message";
import News from "../pages/Home/News";
import Detail from "../pages/Home/Message/Detail";
export default [
{
path: "/about",
element: <About />,
},
{
path: "/home",
element: <Home />,
children: [
{
path: "message",
element: <Message />,
children: [
{
path: "detail",
element: <Detail />,
},
],
},
{
path: "news",
element: <News />,
},
],
},
{
path: "/",
element: <Navigate to="/about" />,
},
];
07-路由的 search 参数\pages\Home\Message\index.jsx
import React, { Component, useState } from "react";
import { Link, NavLink, Outlet } from "react-router-dom";
export default function Message() {
const [message] = useState([
{ id: 1, title: "消息1", content: "内容1" },
{ id: 2, title: "消息2", content: "内容2" },
{ id: 3, title: "消息3", content: "内容3" },
{ id: 4, title: "消息4", content: "内容4" },
]);
return (
<div>
<ul>
{message.map((el) => {
return (
<li key={el.id}>
{/* 路由 search 参数 */}
<Link
to={`detail?id=${el.id}&title=${el.title}&content=${el.content}&`}
>
{el.title}
</Link>
</li>
);
})}
</ul>
<hr />
{/* 指定 Detail 的展示位置 */}
<Outlet />
</div>
);
}
07-路由的 search 参数\pages\Home\Message\Detail\index.jsx
import React from "react";
import { useLocation, useSearchParams } from "react-router-dom";
export default function Detail() {
const [search, setSearch] = useSearchParams();
const id = search.get("id");
const title = search.get("title");
const content = search.get("content");
const _history = useLocation();
console.log(_history);
return (
<div>
<button onClick={() => setSearch("id=123&title=123&content=123")}>
点我更新收到的 search 参数
</button>
<span>{id}</span> -<span>{title}</span> -<span>{content}</span>
</div>
);
}
08-路由的 state 参数
08-路由的 state 参数\routers\index.js
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
import Message from "../pages/Home/Message";
import News from "../pages/Home/News";
import Detail from "../pages/Home/Message/Detail";
export default [
{
path: "/about",
element: <About />,
},
{
path: "/home",
element: <Home />,
children: [
{
path: "message",
element: <Message />,
children: [
{
path: "detail",
element: <Detail />,
},
],
},
{
path: "news",
element: <News />,
},
],
},
{
path: "/",
element: <Navigate to="/about" />,
},
];
08-路由的 state 参数\pages\Home\Message\index.jsx
import React, { Component, useState } from "react";
import { Link, NavLink, Outlet } from "react-router-dom";
export default function Message() {
const [message] = useState([
{ id: 1, title: "消息1", content: "内容1" },
{ id: 2, title: "消息2", content: "内容2" },
{ id: 3, title: "消息3", content: "内容3" },
{ id: 4, title: "消息4", content: "内容4" },
]);
return (
<div>
<ul>
{message.map((el) => {
return (
<li key={el.id}>
{/* 路由 search 参数 */}
<Link
to="detail"
state={{
...el,
}}
>
{el.title}
</Link>
</li>
);
})}
</ul>
<hr />
{/* 指定 Detail 的展示位置 */}
<Outlet />
</div>
);
}
08-路由的 state 参数\pages\Home\Message\Detail\index.jsx
import React from "react";
import { useLocation } from "react-router-dom";
export default function Detail() {
const stateCfg = useLocation();
const {
state: { id, title, content },
} = stateCfg;
return (
<div>
<span>{id}</span> -<span>{title}</span> -<span>{content}</span>
</div>
);
}
09-编程式路由
09-编程式路由\pages\Home\Message\index.jsx
import React, { Component, useState } from "react";
import { Link, useNavigate, Outlet } from "react-router-dom";
export default function Message() {
const [message] = useState([
{ id: 1, title: "消息1", content: "内容1" },
{ id: 2, title: "消息2", content: "内容2" },
{ id: 3, title: "消息3", content: "内容3" },
{ id: 4, title: "消息4", content: "内容4" },
]);
const navigate = useNavigate();
function showDetail(message) {
navigate("detail", {
replace: true,
state: message,
});
}
return (
<div>
<ul>
{message.map((el) => {
return (
<li key={el.id}>
{/* 路由 search 参数 */}
<Link
to="detail"
state={{
...el,
}}
>
{el.title}
</Link>
<button onClick={() => showDetail(el)}>查看详情</button>
</li>
);
})}
</ul>
<hr />
{/* 指定 Detail 的展示位置 */}
<Outlet />
</div>
);
}
09-编程式路由\pages\Home\Message\Detail\index.jsx
import React from "react";
import { useLocation } from "react-router-dom";
export default function Detail() {
const stateCfg = useLocation();
const {
state: { id, title, content },
} = stateCfg;
return (
<div>
<span>{id}</span> -<span>{title}</span> -<span>{content}</span>
</div>
);
}
10-uselnRouterContext
10-useInRouterContext\components\Demo.jsx
import React from "react";
import { useInRouterContext } from "react-router-dom";
export default function Demo() {
console.log("demo --- useInRouterContext", useInRouterContext());
return <div>Demo</div>;
}
10-useInRouterContext\components\Header.jsx
import React from "react";
import { useNavigate, useInRouterContext } from "react-router-dom";
export default function Header() {
const navigate = useNavigate();
console.log("header --- useInRouterContext", useInRouterContext());
function back(params) {
navigate(-1);
}
function forward(params) {
navigate(1);
}
return (
<div>
<button onClick={back}>后退</button>
<button onClick={forward}>前进</button>
</div>
);
}
11-useNavigationType
import React, { Component } from "react";
import { useNavigationType } from "react-router-dom";
export default function News() {
console.log("News --- useNavigationType", useNavigationType());
return (
<div>
<ul>
<li>News 1</li>
<li>News 2</li>
<li>News 3</li>
<li>News 3</li>
</ul>
</div>
);
}
12-useOutlet
import React, { Component, useState } from "react";
import { NavLink, Outlet, useOutlet } from "react-router-dom";
export default function Home() {
console.log("Home --- useOutlet", useOutlet());
return (
<div style={{ padding: "10px" }}>
<div style={{ border: "1px solid red" }}>
<h2>导航区</h2>
<div>
<a style={{ float: "left", marginRight: "10px" }}>About</a>
<a style={{ color: "red" }}>Home</a>
</div>
</div>
<div style={{ border: "1px solid green", marginTop: "10px" }}>
<h2>展示区</h2>
<h2>Home</h2>
<NavLink to="message">Message</NavLink>
<NavLink to="news">News</NavLink>
{/* 指定路由组件呈现的位置, 类似Vue的 route-view */}
<Outlet />
</div>
</div>
);
}
13-useResolvedPath
import React, { Component } from "react";
import { useResolvedPath } from "react-router-dom";
export default function News() {
console.log(
"useResolvedPath",
useResolvedPath("/user?id=001&name=tom#qwert")
);
return (
<div>
<ul>
<li>News 1</li>
<li>News 2</li>
<li>News 3</li>
<li>News 3</li>
</ul>
</div>
);
}