ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从手写 Hash 路由到 React Router:一个路由练习的关键实现

从手写 Hash 路由到 React Router:一个路由练习的关键实现

从手写 Hash 路由到 React Router:一个路由练习的关键实现

前端路由的目标是在单页应用中根据 URL 切换页面组件,而不按传统多页应用方式重新请求整份 HTML。本练习基于 React、Vite 和react-router-dom,集中实现了基础路由、动态参数、嵌套路由、404 与路由级懒加载。

本文依据本地代码静态分析整理,运行未验证。

1. 用 Router 接管页面切换

入口路由在App.jsx

<Router> <Suspense fallback={<div>Loading...</div>}> <Navigation /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/user/:id" element={<UserProfile />} /> <Route path="*" element={<NotFound />} /> </Routes> </Suspense> </Router>

项目将HashRouter别名为Router。它使用#后的路径管理前端状态,例如#/aboutRoutes负责匹配,Route描述“路径对应哪个组件”。

导航栏用Link

<Link to="/about">About</Link>

Link让 React Router 处理跳转,适用于 SPA 路由切换。

2. 路由级懒加载:首屏不必下载全部页面

页面不是普通静态导入,而是:

const Home = lazy(() => import('./pages/Home')) const Products = lazy(() => import('./pages/Products'))

lazy + import()实现代码分割:访问页面时才加载对应模块。由于异步加载需要等待时间,外层必须由Suspense包裹并显示加载占位。

这适合管理后台、图表、编辑器或访问频率低的页面;不应把每个很小且高频的组件都拆分成独立包。

3. 动态参数:同一页面处理不同资源

用户页规则:

<Route path="/user/:id" element={<UserProfile />} />

访问/user/123后:

const { id } = useParams()

可得到字符串'123'。产品详情使用相同模式读取:productId

真实业务中,参数通常用于请求详情接口,并应处理参数格式校验、加载状态和接口异常。

4. 嵌套路由:共享布局与子页面出口

产品模块:

<Route path="/products" element={<Products />}> <Route path=":productId" element={<ProductDetail />} /> <Route path="new" element={<ProductNew />} /> </Route>

父组件提供:

<Outlet />

当访问/products/123时,Products先渲染共享标题,ProductDetail再渲染到Outlet位置。该模式适合共享侧栏、Tab、权限逻辑的业务模块。

5. 404、重定向与编程式跳转

未知地址由通配符兜底:

<Route path="*" element={<NotFound />} />

404 页通过useNavigate在逻辑中跳转:

const navigate = useNavigate() navigate('/')

Navigate用于声明式重定向:

<Route path="/old-path" element={<Navigate to="/new-path" />} />

两个代码审查点

  1. /new-path未见对应路由配置,按当前代码推断会进入 404;需要补充目标路由或修改跳转目标。
  2. 404 页创建了 3 秒定时器但没有清理。建议在useEffect中返回clearTimeout(timer),避免组件提前卸载后仍触发跳转。

6. 小结

这个练习覆盖了 React Router 的主干能力:

  • HashRouter提供路由上下文;
  • RoutesRoute描述路径与页面;
  • Link用于导航;
  • lazy + Suspense用于按需加载;
  • useParams读取动态参数;
  • Outlet承载嵌套路由;
  • NavigateuseNavigate分别处理声明式与编程式跳转;
  • path="*"负责 404 兜底。

面试中可以总结为:我完成了一个 React SPA 路由练习,并在基础路由之上补充了页面级代码分割、动态参数和嵌套路由;同时关注到重定向目标必须存在、异步副作用必须清理等可靠性问题。

返回列表