React Router 6 - 编程式路由导航、useInRouterContext、useNavigationType

一、编程式路由导航

1、基本介绍
  • useNavigate 用于 返回一个函数用来实现编程式导航,它有 2 种使用方式
  1. 指定具体的路径

  2. 传入数值进行前进或后退,类似于 5.x 中的 history.go()

2、演示
(1)page
  1. 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>
    );
}
  1. 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>
    );
}
  1. 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>
    );
}
  1. 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
  1. App 组件
tsx 复制代码
import { useRoutes } from "react-router-dom";
import routes from "./routes";

export default function App() {
    const element = useRoutes(routes);

    return <div>{element}</div>;
}
  1. 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、演示
  1. Demo 组件
tsx 复制代码
import { useInRouterContext } from "react-router-dom";

export default function Demo() {
    const result = useInRouterContext();
    console.log(result);

    return <div>Demo</div>;
}
  1. App 组件
tsx 复制代码
export default function App() {
    return <div>App</div>;
}
  1. 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、基本介绍
  1. useNavigationType 用于返回当前的导航类型,导航类型表示用户是如何来到当前页面的

  2. 返回值有 POPPUSHREPLACE

  3. POP 是指在浏览器中直接打开了这个路由组件(刷新页面),或者前进后退

2、演示
(1)page
  1. 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>
    );
}
  1. 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>
    );
}
  1. 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>
    );
}
  1. 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
  1. App 组件
tsx 复制代码
import { useRoutes } from "react-router-dom";
import routes from "./routes";

export default function App() {
    const element = useRoutes(routes);

    return <div>{element}</div>;
}
  1. 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>,
);
相关推荐
REDcker9 小时前
个人博客网站建设指南 Markdown资产化与静态站选型部署
前端·后端·博客·markdown·网站·资产·建站
zhangfeng11339 小时前
小龙虾 wordbuddy 安装浏览器控制器 agent-browser npm install -g agent-browse
前端·人工智能·npm·node.js
徐小夕9 小时前
100小时,我做了一款AI CAD建模软件,开源!
前端·vue.js·github
Bigger9 小时前
因为看不懂小棉袄的画,我写了个 AI 程序帮我“翻译”她的世界
前端·人工智能·ai编程
送鱼的老默10 小时前
学习笔记--入门typescript直接案例开搞
前端·typescript
Prometheus10 小时前
从 XMLHttpRequest 到 fetch、ReadableStream、SSE、EventSource:前端流式通信完整梳理
前端
光影少年10 小时前
useEffect 完整理解:依赖数组、副作用清理、模拟生命周期
前端·react.js·程序员
之歆10 小时前
DAY_18深度解析:数据类型转换与运算符全攻略(上)
前端·javascript
大家的林语冰10 小时前
pnpm 11 发布,弃用 JSON 和 npm CLI,进化为纯 ES6 模块,新增 pnpm pack-app 等命令,供应链保护默认启用,要求 Node
前端·javascript·node.js
漓漾li11 小时前
每日面试题-前端2
前端·react.js·面试