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>,
);
相关推荐
BillKu5 小时前
Element Plus 的 el-tab-pane:lazy 的说明
前端·javascript·vue.js
爱勇宝5 小时前
《道德经》第 11 章:真正有用的,常常是你没写出来的那部分
前端·后端·产品
jearry5 小时前
WebView2 原生拖放的桥接之道:拆解 yyzTools 的 drop-zone.js
前端·c++
一位正在转型AI全栈的前端工程师5 小时前
AI 全栈学习之旅 -Week 11:从 CLI 到浏览器:用 FastAPI、SSE 和 Vue 3 做一个可审核的 ReAct Agent
前端·python
10share5 小时前
我为什么用 React 重写了一个 VitePress
前端·react.js
计算机魔术师5 小时前
GPT-6 Astra 发布后,Sebastian Raschka 解析 looped transformer 与隐藏推理链传闻
前端
不可能片场5 小时前
Electron 退化成 node:一个环境变量的锅
前端·electron
楚楚河河5 小时前
js 变量声明
前端
Cicada1286 小时前
Web 服务器怎么选
运维·服务器·前端
不可能片场6 小时前
接口返回 200 不代表活着:catch-all 路由的陷阱
前端·electron