这是本专栏的第一篇文章,用来记录一个基于react-router v7 的路由系统的从创建到完善的过程,以及过程中的思考 ~
概览
react-router-dom 安装 与 antd 组件结合实现基础路由系统
先来大致回顾一下 react-touter v7 的重要变化
- React 19 支持 - v7 针对 React 19 做了适配
- 非破坏性升级 - 从 v6 升级到 v7 不会破坏现有代码
- 框架化定位 - v7 定位为全栈框架,支持数据加载等新特性
react-router-dom
首先我们需要将 react-router 引入 reactv19。这里我选择使用 react-router-dom v7 .
shell
npm install react-router-dom
补充: 是 react-router 在浏览器环境下的专门实现(DOM 环境) ,它依赖并封装了 react-router ,在核心库的基础上,增加了适合浏览器环境的路由组件和功能(如 BrowserRouter、HashRouter、Link 等)。
页面配置
js
import { BrowserRouter, Routes, Route } from 'react-router-dom'
function App() {
return (
<BrowserRouter>
<Routes>
{/* Layout 在 React Router 中的使用方式是作为父路由, 通过 <Outlet /> 来渲染子路由的内容 */}
<Route path="/" element={<Layout />}>
<Route index path="chat" element={<Chat />}></Route>
<Route path="shiti" element={<ShiTi />}></Route>
<Route path="file" element={<UploadPage />}></Route>
</Route>
</Routes>
</BrowserRouter>
)
}
layout.tsx --- 结合antd 的 Menu 组件进行配置
js
import { Menu } from "antd"
import { Outlet } from "react-router-dom";
import useRouterHook from './useRouterHook';
import * as styles from './index.module.less';
const Layout = () => {
const { onClick, current, items } = useRouterHook();
return (
<div className={styles.container}>
<Menu
className={styles.menu}
onClick={onClick}
selectedKeys={[current]}
mode="horizontal"
items={items}
/>
<div className={styles.main}>
<Outlet />
</div>
</div>
)
}
export default Layout;
封装 useRouterHook
思路:
- 将 文件路径做为 key 存放到 Menu 的item 中,
- 点击 Menu 触发 onClick 事件,使用 useNavigator 进行路由切换
- 监听 useLocation 的 pathname 属性,页面路由发生变化的时候,改变当前 current menu 值
tsx
import { MenuProps } from "antd";
import { useEffect, useState } from "react";
import { AppstoreOutlined, MailOutlined, SettingOutlined } from '@ant-design/icons';
import { useLocation, useNavigate } from "react-router-dom";
const useRouterHook = () => {
const navigate = useNavigate();
const location = useLocation();
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuItem[] = [
{ label: "聊天", key: "/chat", icon: <AppstoreOutlined />, },
{ label: "试题", key: "/shiti", icon: <MailOutlined /> },
{ label: "文件", key: "/file", icon: <SettingOutlined /> }
]
const [current, setCurrent] = useState<string>('/chat')
const onClick:MenuProps['onClick'] = (e) => {
setCurrent(e.key) navigate(e.key)
}
useEffect(() => {
setCurrent(location.pathname)
}, [location.pathname])
return { current, onClick, items }
}
export default useRouterHook
页面效果:

OK,接入完成
下一步,利用webpack 编译时注入的变量 require 实现约定式路由 ~ juejin.cn/post/759366...