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 对象,让开发者能够获取和监听当前路由信息

相关推荐
JieE2126 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
runnerdancer7 小时前
LLM是怎么处理messages数组的,提示词缓存又是什么
前端·agent
陈随易7 小时前
VSCode的Copilot扩展支持接入DeepSeek,Kimi了!
前端·后端·程序员
我不是外星人9 小时前
有了 Harness Engineering ,真的还需要研发工程师吗?
前端·后端·ai编程
candyTong9 小时前
RTK 技术原理:一次典型会话里,80% 上下文是怎么省下来的
javascript·后端·架构
IT_陈寒11 小时前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
Jackson__12 小时前
分享一个横向滚动案例,带悬停暂停,通用性很强
前端
MariaH13 小时前
git rebase的使用
前端
_柳青杨13 小时前
深入理解 JavaScript 事件循环
前端·javascript
阡陌Jony13 小时前
关于前端性能优化的一些问题:
前端