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>,
);
相关推荐
恋猫de小郭6 分钟前
AI Agent 开发究竟是啥?如何用 AI 开发 Agent ?深入浅出给你一套概念
android·前端·ai编程
前端双越老师8 分钟前
我开发 AI Agent 项目踩过的 5个坑
前端·agent·全栈
晓得迷路了30 分钟前
栗子前端技术周刊第 134 期 - React Router v8、TypeScript 7 RC、React Native 0.86...
前端·javascript·react.js
Carson带你学Android31 分钟前
Android 17 正式发布:AI 终于成了系统能力
android·前端·ai编程
Mike_jia42 分钟前
ZbxTable:Zabbix开源报表神器,从运维数据到决策洞察的最后一公里
前端
LinXunFeng10 小时前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
乘风gg14 小时前
为什么AI 时代来临,大部分人吃不到红利
前端·ai编程·claude
恋猫de小郭14 小时前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
IT_陈寒14 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
恋猫de小郭14 小时前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter