一、编程式路由导航
1、基本介绍
- useNavigate 用于 返回一个函数用来实现编程式导航,它有 2 种使用方式
-
指定具体的路径
-
传入数值进行前进或后退,类似于 5.x 中的
history.go()
2、演示
(1)page
- Message 页面
tsx
import { useState } from "react";
import { Outlet, useNavigate } from "react-router-dom";
export default function Message() {
const [messages] = useState([
{ id: "01", title: "消息 1" },
{ id: "02", title: "消息 2" },
{ id: "03", title: "消息 3" },
]);
const navigate = useNavigate();
function showDetailParams(id, title) {
navigate(`/message/detail/${id}/${title}`);
}
function showDetailSearch(id, title) {
navigate(`/message/news?id=${id}&title=${title}`);
}
function showDetailState(id, title) {
navigate(`/message/tip`, {
replace: true,
state: {
id: id,
title: title,
},
});
}
function handleBack() {
navigate(-1);
}
function handleForward() {
navigate(1);
}
return (
<div>
<h3>传递 params 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<button onClick={() => showDetailParams(item.id, item.title)}>{item.title}</button>
</li>
))}
</ul>
<h3>传递 search 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<button onClick={() => showDetailSearch(item.id, item.title)}>{item.title}</button>
</li>
))}
</ul>
<h3>传递 state 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<button onClick={() => showDetailState(item.id, item.title)}>{item.title}</button>
</li>
))}
</ul>
<Outlet />
<div>
<button onClick={handleBack}>back</button>
<button onClick={handleForward}>forward</button>
</div>
</div>
);
}
- Detail 页面
tsx
import { useParams } from "react-router-dom";
export default function Detail() {
const { id, title } = useParams();
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
- News 页面
tsx
import { useSearchParams } from "react-router-dom";
export default function News() {
const [search, setSearch] = useSearchParams();
const id = search.get("id");
const title = search.get("title");
return (
<div>
<button onClick={() => setSearch("id=04&title=消息 4")}>点击更新一下收到的 search 参数</button>
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
</div>
);
}
- Tip 页面
tsx
import { useLocation } from "react-router-dom";
export default function Tip() {
const {
state: { id, title },
} = useLocation();
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
(2)route
- index.tsx
tsx
import Message from "../pages/Message";
import Detail from "../pages/Detail";
import News from "../pages/News";
import Tip from "../pages/Tip";
import { Navigate } from "react-router-dom";
export default [
{
path: "/message",
element: <Message />,
children: [
{
path: "detail/:id/:title",
element: <Detail />,
},
{
path: "news",
element: <News />,
},
{
path: "tip",
element: <Tip />,
},
],
},
{
path: "/",
element: <Navigate to="/message" />,
},
];
(3)main
- App 组件
tsx
import { useRoutes } from "react-router-dom";
import routes from "./routes";
export default function App() {
const element = useRoutes(routes);
return <div>{element}</div>;
}
- main.tsx
tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);
二、useInRouterContext
1、基本介绍
- 如果组件在
<Router>的上下文中呈现,则 useInRouterContext 返回 true,否则返回 false
2、演示
- Demo 组件
tsx
import { useInRouterContext } from "react-router-dom";
export default function Demo() {
const result = useInRouterContext();
console.log(result);
return <div>Demo</div>;
}
- App 组件
tsx
export default function App() {
return <div>App</div>;
}
- main.tsx
tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App.tsx";
import Demo from "./components/Demo.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<Demo />
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);
输出结果
false
tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App.tsx";
import Demo from "./components/Demo.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<BrowserRouter>
<Demo />
<App />
</BrowserRouter>
</StrictMode>,
);
输出结果
true
三、useNavigationType
1、基本介绍
-
useNavigationType 用于返回当前的导航类型,导航类型表示用户是如何来到当前页面的
-
返回值有
POP、PUSH、REPLACE -
POP是指在浏览器中直接打开了这个路由组件(刷新页面),或者前进后退
2、演示
(1)page
- Message 页面
tsx
import { useState } from "react";
import { Outlet, useNavigate } from "react-router-dom";
export default function Message() {
const [messages] = useState([
{ id: "01", title: "消息 1" },
{ id: "02", title: "消息 2" },
{ id: "03", title: "消息 3" },
]);
const navigate = useNavigate();
function showDetailParams(id, title) {
navigate(`/message/detail/${id}/${title}`);
}
function showDetailSearch(id, title) {
navigate(`/message/news?id=${id}&title=${title}`);
}
function showDetailState(id, title) {
navigate(`/message/tip`, {
replace: true,
state: {
id: id,
title: title,
},
});
}
function handleBack() {
navigate(-1);
}
function handleForward() {
navigate(1);
}
return (
<div>
<h3>传递 params 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<button onClick={() => showDetailParams(item.id, item.title)}>{item.title}</button>
</li>
))}
</ul>
<h3>传递 search 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<button onClick={() => showDetailSearch(item.id, item.title)}>{item.title}</button>
</li>
))}
</ul>
<h3>传递 state 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<button onClick={() => showDetailState(item.id, item.title)}>{item.title}</button>
</li>
))}
</ul>
<Outlet />
<div>
<button onClick={handleBack}>back</button>
<button onClick={handleForward}>forward</button>
</div>
</div>
);
}
- Detail 页面
tsx
import { useParams } from "react-router-dom";
export default function Detail() {
const { id, title } = useParams();
const result = useNavigationType();
console.log(result);
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
- News 页面
tsx
import { useSearchParams } from "react-router-dom";
export default function News() {
const [search, setSearch] = useSearchParams();
const id = search.get("id");
const title = search.get("title");
const result = useNavigationType();
console.log(result);
return (
<div>
<button onClick={() => setSearch("id=04&title=消息 4")}>点击更新一下收到的 search 参数</button>
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
</div>
);
}
- Tip 页面
tsx
import { useLocation } from "react-router-dom";
export default function Tip() {
const {
state: { id, title },
} = useLocation();
const result = useNavigationType();
console.log(result);
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
(2)route
- index.tsx
tsx
import Message from "../pages/Message";
import Detail from "../pages/Detail";
import News from "../pages/News";
import Tip from "../pages/Tip";
import { Navigate } from "react-router-dom";
export default [
{
path: "/message",
element: <Message />,
children: [
{
path: "detail/:id/:title",
element: <Detail />,
},
{
path: "news",
element: <News />,
},
{
path: "tip",
element: <Tip />,
},
],
},
{
path: "/",
element: <Navigate to="/message" />,
},
];
(3)main
- App 组件
tsx
import { useRoutes } from "react-router-dom";
import routes from "./routes";
export default function App() {
const element = useRoutes(routes);
return <div>{element}</div>;
}
- main.tsx
tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);