React Router 6 - 嵌套路由、路由传递参数

一、嵌套路由

1、基本介绍
  1. 默认情况下,子组件匹配成功,父组件的导航也会高亮,当 NavLink 上添加了 end 属性后,子组件匹配成功,父组件的导航不会高亮

  2. <Outlet> 组件用于,当前 <Route> 产生嵌套时,渲染其对应的后续子路由

2、演示
(1)page
  1. About 页面
tsx 复制代码
export default function About() {
    return <h3>About Content</h3>;
}
  1. Home 页面
tsx 复制代码
import { NavLink, Outlet } from "react-router-dom";

export default function Home() {
    function computedClassName({ isActive }) {
        return isActive ? "my-item active" : "my-item";
    }

    return (
        <div>
            <h3>Home Content</h3>
            <ul>
                <li>
                    <NavLink className={computedClassName} to="news">
                        News
                    </NavLink>
                </li>
                <li>
                    <NavLink className={computedClassName} to="message">
                        Message
                    </NavLink>
                </li>
            </ul>
            <Outlet />
        </div>
    );
}
  1. News 页面
tsx 复制代码
export default function News() {
    return (
        <ul>
            <li>news001</li>
            <li>news002</li>
            <li>news003</li>
        </ul>
    );
}
  1. Message 页面
tsx 复制代码
export default function Message() {
    return (
        <div>
            <ul>
                <li>
                    <a href="/message1">message001</a>&nbsp;&nbsp;
                </li>
                <li>
                    <a href="/message2">message002</a>&nbsp;&nbsp;
                </li>
                <li>
                    <a href="/message3">message003</a>&nbsp;&nbsp;
                </li>
            </ul>
        </div>
    );
}
(2)route
  • index.tsx
tsx 复制代码
import About from "../pages/About";
import Home from "../pages/Home";
import News from "../pages/News";
import Message from "../pages/Message";
import { Navigate } from "react-router-dom";

export default [
    {
        path: "/about",
        element: <About />,
    },
    {
        path: "/home",
        element: <Home />,
        children: [
            {
                path: "news",
                element: <News />,
            },
            {
                path: "message",
                element: <Message />,
            },
        ],
    },
    {
        path: "/",
        element: <Navigate to="/about" />,
    },
];
(3)main
  1. App 组件
tsx 复制代码
import { NavLink, useRoutes } from "react-router-dom";
import routes from "./routes";
import "./App.css";

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

    function computedClassName({ isActive }) {
        return isActive ? "my-item active" : "my-item";
    }

    return (
        <div>
            <div>
                <NavLink className={computedClassName} to="/about">
                    About
                </NavLink>
                <NavLink className={computedClassName} to="/home">
                    Home
                </NavLink>
            </div>
            <div>{element}</div>
        </div>
    );
}
css 复制代码
.my-item {
    padding: 10px;
    cursor: pointer;
}

.active {
    color: red;
}
  1. index.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>,
);

二、路由传递参数

1、演示
(1)page
  1. Message 页面
tsx 复制代码
import { useState } from "react";
import { NavLink, Outlet } from "react-router-dom";

export default function Message() {
    const [messages] = useState([
        { id: "01", title: "消息 1" },
        { id: "02", title: "消息 2" },
        { id: "03", title: "消息 3" },
    ]);

    return (
        <div>
            <h3>传递 params 参数</h3>
            <ul>
                {messages.map((item) => (
                    <li key={item.id}>
                        <NavLink to={`/message/detail/${item.id}/${item.title}`}>{item.title}</NavLink>
                    </li>
                ))}
            </ul>

            <h3>传递 search 参数</h3>
            <ul>
                {messages.map((item) => (
                    <li key={item.id}>
                        <NavLink to={`/message/news?id=${item.id}&title=${item.title}`}>{item.title}</NavLink>
                    </li>
                ))}
            </ul>

            <h3>传递 state 参数</h3>
            <ul>
                {messages.map((item) => (
                    <li key={item.id}>
                        <NavLink to="/message/tip" state={{ id: item.id, title: item.title }}>
                            {item.title}
                        </NavLink>
                    </li>
                ))}
            </ul>

            <Outlet />
        </div>
    );
}
  1. Detail 页面
tsx 复制代码
import { useParams, useMatch } from "react-router-dom";

export default function Detail() {
    const { id, title } = useParams();

    // const x1 = useMatch("/message/detail/:id/:title");
    // console.log(x1);
    // const x2 = useMatch("/message/detail/:id");
    // console.log(x2);

    return (
        <ul>
            <li>id: {id}</li>
            <li>title: {title}</li>
        </ul>
    );
}
  1. News 页面
tsx 复制代码
import { useSearchParams, useLocation } from "react-router-dom";

export default function News() {
    const [search, setSearch] = useSearchParams();
    const id = search.get("id");
    const title = search.get("title");

    const x = useLocation();
    console.log(x);

    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>,
);
2、补充学习
  1. useParams:用于返回当前匹配路由的 params 参数

  2. useSearchParams:用于读取和修改当前位置的 URL 中的查询字符串,返回一个包含两个值的数组,内容分别为,当前的 search 参数、更新 search 的函数

  3. useMatch:用于匹配当前 URL 是否与指定路径模式匹配,如果不匹配,返回 null

  4. useLocation:用于返回当前 URL 的 location 对象,让开发者能够获取和监听当前路由信息

相关推荐
Csvn6 分钟前
事件循环与渲染时机:一文吃透宏任务、微任务和 rAF
前端
章鱼小丸子逃跑中12 分钟前
【2025最新版】如何将fnm与node.js安装在D盘?【保姆级安装及人性话理解教程】
前端·javascript·npm·node.js
Larcher28 分钟前
从 SDD 到可交付:我如何用规范驱动 AI 做出一个 Chrome 翻译插件
前端·后端·架构
suaizai_1 小时前
AI Agent如何懂你:四层能力拆解
java·前端·人工智能
invicinble1 小时前
把握前端项目的核心(vibecoding)
前端
0end12 小时前
AI Agent 学习笔记(三):上下文工程(下)—— KV Cache、提示词设计与 Agent Skills
前端·aigc·ai编程
CAD老兵2 小时前
在浏览器里对比 DWG/DXF 图纸 —— @mlightcad/cad-diff-viewer
前端·javascript·github
JasonYin2 小时前
AI 定义的 H5移动端 开发规范,直接抄作业!
前端
诗章与猫2 小时前
Leaflet 渲染 100 万 marker 卡成 PPT?我用 WebGL 重写了渲染器
前端
用户921080262862 小时前
在 AI 代码生成项目里接入 Thought:别展示“玄学思维链”,只展示用户真正关心的工具调用
前端