{"id":20082604,"url":"https://github.com/lexmin0412/pure-react-router","last_synced_at":"2026-03-02T13:35:50.621Z","repository":{"id":259409632,"uuid":"877233792","full_name":"lexmin0412/pure-react-router","owner":"lexmin0412","description":"一个干净的 React Router 实现，API 参考了 React Router 但大幅简化。","archived":false,"fork":false,"pushed_at":"2024-11-21T08:20:27.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-21T15:13:46.413Z","etag":null,"topics":["lightweight-router","pure-router","react","react-router","router"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lexmin0412.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-23T10:12:27.000Z","updated_at":"2024-11-21T08:20:31.000Z","dependencies_parsed_at":"2024-10-25T06:17:49.690Z","dependency_job_id":"a63f443e-354f-4451-9785-a83bf11a699b","html_url":"https://github.com/lexmin0412/pure-react-router","commit_stats":null,"previous_names":["lexmin0412/pure-react-router"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexmin0412%2Fpure-react-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexmin0412%2Fpure-react-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexmin0412%2Fpure-react-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexmin0412%2Fpure-react-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lexmin0412","download_url":"https://codeload.github.com/lexmin0412/pure-react-router/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233682437,"owners_count":18713551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lightweight-router","pure-router","react","react-router","router"],"created_at":"2024-11-13T15:44:14.097Z","updated_at":"2025-09-20T18:32:34.452Z","avatar_url":"https://github.com/lexmin0412.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pure React Router\n\n![NPM Downloads](https://img.shields.io/npm/dm/pure-react-router)\n![version](https://img.shields.io/npm/v/pure-react-router)\n![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/pure-react-router/latest)\n![NPM Last Update](https://img.shields.io/npm/last-update/pure-react-router)\n![GitHub commit activity](https://img.shields.io/github/commit-activity/y/lexmin0412/pure-react-router)\n\n基于 React 的 **超轻量** 路由库，参考了 React Router 但大幅精简了 API。\n\n## 介绍\n\n### 特性\n\n- ✈️ **极致轻量** - 压缩后仅 1.2kb，除宿主自带 React 外，零第三方依赖\n- ♻️ **平滑迁移** - 兼容 React Router 核心 API\n- 🚀 **未来无忧** - 专注路由核心功能，拒绝框架膨胀\n- ⚡ **TypeScript 优先** - 完整的类型定义支持\n\n### 为什么要有 Pure React Router?\n\n每次创建新项目时，我一般习惯将基础依赖如 React、React Router 等升级到最新的稳定版本，但当我将旧的路由代码迁移到新的项目时，发现 React Router API 又发生了变更导致运行时报错 [^崩溃^]。\n\n压垮骆驼的最后一根稻草，是在 [React Conf 2024 上，Remix 团队宣布在即将发布的 React Router v7.0 中，将 React Router 和 Remix 进行合并](https://remix.run/blog/merging-remix-and-react-router)，是的没看错，它正式成为了一个全栈框架。\n\n众所周知，对于大型框架如 Next.js、Tanstack 等的路由系统为了支持复杂的功能，往往会有繁杂的 API 和不知隐藏在何处的文档，而这次，我再也不想将就了。`Pure React Router` 由此应运而生，你再也不用担心你的路由库会变成一个巨石框架的一部分了。\n\n## 快速开始\n\n### 安装\n\n```bash\npnpm install pure-react-router\n# 或\nnpm install pure-react-router\n# 或\nyarn add pure-react-router\n```\n\n### 基础示例\n\n```tsx\n// 在根组件中初始化路由\nimport { BrowserRouter, Route } from \"pure-react-router\";\nimport Home from \"./pages/Home\";\nimport About from \"./pages/About\";\n\n// 路由配置（支持树形结构）\nconst routes = [\n  { path: \"/home\", component: Home },\n  { path: \"/about\", component: About },\n  { path: \"/\", redirect: \"/home\" }, // 支持重定向\n];\n\nexport default function App() {\n  return (\n    \u003cBrowserRouter routes={routes} basename=\"/webapp\"\u003e\n      \u003cRoute /\u003e\n    \u003c/BrowserRouter\u003e\n  );\n}\n```\n\n## 📚 核心 API\n\n### 组件\n\n#### BrowserRouter\n\n路由容器。接收一个扁平的 routes 数组配置。\n\n属性：\n\n- `basename` 路由前缀\n- `routes` 路由配置\n\n场景应用：在应用入口文件中定义路由结构。\n\n```tsx\nconst RouteList = [\n  { path: \"/default-page\", component: DefaultPage },\n  { path: \"/others-page\", component: OthersPage },\n  { path: \"/\", component: Test5 },\n];\n\nconst App = () =\u003e {\n  return (\n    \u003cBrowserRouter routes={RouteList} basename=\"/webapp\"\u003e\n      页面内容 (内部需嵌套 \u003cRoute /\u003e 组件使用)\n    \u003c/BrowserRouter\u003e\n  );\n};\n\nconst root = ReactDOM.createRoot(document.getElementById(\"root\")!);\nroot.render(\n  \u003cReact.StrictMode\u003e\n    \u003cApp /\u003e\n  \u003c/React.StrictMode\u003e\n);\n```\n\n#### Route\n\n路由占位组件，根据路由变化自动切换渲染内容。\n\n```tsx\nconst App = () =\u003e {\n  return (\n    \u003cBrowserRouter routes={RouteList} basename=\"webapp\"\u003e\n      {/* 页面其他部分 */}\n      \u003cOtherLayout /\u003e\n      {/* 路由组件 */}\n      \u003cRoute /\u003e\n    \u003c/BrowserRouter\u003e\n  );\n};\n```\n\n#### Link\n\n跳转组件，用于替换 a 标签。\n\n属性：\n\n- `className` a 标签类名，可选\n- `to` 目标路径(无需拼接 basename)\n- `children` 链接文本元素(可以是 React 组件)\n\n场景应用：跳转到其他路由。\n\n```tsx\nexport default function App() {\n  return (\n    \u003cLink className=\"text-blue\" to=\"/test1\"\u003e\n      test1\n    \u003c/Link\u003e\n  );\n}\n```\n\n### Hooks\n\n#### useHistory\n\n获取 history 对象。\n\n场景应用：监听 pathname 变更修改页面标题。\n\n```tsx\nimport { useHistory } from \"pure-react-router\";\nimport pkgJson from \"../package.json\";\n\nexport default function App() {\n  const history = useHistory();\n\n  useEffect(() =\u003e {\n    if (history.location.pathname.includes(\"detail\")) {\n      document.title = `详情`;\n    }\n    document.title = pkgJson.name;\n  }, [history.location.pathname]);\n\n  return \u003cdiv\u003eContent\u003c/div\u003e;\n}\n```\n\n#### useParams\n\n获取 URL 中的 Path 参数。\n\n场景应用：获取 Path 中的 id 查询详情。\n\n示例：路由定义为 `/detail/:id`, 页面实际路径为 `/detail/123`，则 `useParams()` 的返回结果为 `{id: '123'}`\n\n```tsx\nimport { useState } from \"react\";\nimport { useParams } from \"pure-react-router\";\n\nexport default function App() {\n  const params = useParams();\n  const [detail, setDetail] = useState();\n\n  const getDetail = async (id: string) =\u003e {\n    const result = await promise();\n    setDetail(result);\n  };\n\n  useEffect(() =\u003e {\n    getDetail(params.id);\n  }, []);\n\n  return \u003cdiv\u003e{detail}\u003c/div\u003e;\n}\n```\n\n#### useSearchParams\n\n获取 URL 中的参数，等价于 `new URLSearchParams(window.location.pathname)`。\n\n场景应用：获取 URLSearchParams 中的 id 查询详情。\n\n```tsx\nimport { useSearchParams } from \"pure-react-router\";\n\nexport default function App() {\n  const searchParams = useSearchParams();\n  const [detail, setDetail] = useState();\n\n  const getDetail = async (id: string) =\u003e {\n    const result = await promise();\n    setDetail(result);\n  };\n\n  useEffect(() =\u003e {\n    getDetail(searchParams.get(\"id\"));\n  }, []);\n\n  return \u003cdiv\u003e{detail}\u003c/div\u003e;\n}\n```\n\n#### useMatchRoute\n\n获取当前匹配的路由信息，同 `matchRoute(history.location.pathname, routes)`。\n\n场景应用：处理 404 页面跳转逻辑。\n\n```tsx\nimport {\n  useMatchRoute,\n  useHistory,\n  PureRouterContext,\n  Route,\n} from \"pure-react-router\";\n\nexport default function App() {\n  const { routes } = useContext(PureRouterContext);\n  const history = useHistory();\n  const { route } = useMatchRoute();\n\n  useEffect(() =\u003e {\n    if (!route) {\n      history.push(\"/common/404\");\n    }\n  }, [history.location.pathname]);\n}\n```\n\n#### PureRouterContext\n\n全局上下文。\n\n场景应用：深层嵌套子组件获取 basename 配置。\n\n```tsx\nimport { useContext } from \"react\";\nimport { PureRouterContext } from \"pure-react-router\";\n\nexport default function DeepNestedComponent() {\n  const { basename } = useContext(PureRouterContext);\n\n  return \u003cdiv\u003e当前应用：{basename}\u003c/div\u003e;\n}\n```\n\n### Utils\n\n#### matchRoute\n\n获取指定路径匹配的路由信息。\n\n场景应用：特殊处理某个路由的渲染。\n\n```tsx\nimport {\n  matchRoute,\n  useHistory,\n  PureRouterContext,\n  Route,\n} from \"pure-react-router\";\n\nexport default function App() {\n  const history = useHistory();\n  const { routes } = useContext(PureRouterContext);\n  const { route } = matchRoute(\"/home\", routes);\n\n  if (history.location.pathname === \"/home\") {\n    return \u003cHome specialPropName=\"\" /\u003e;\n  } else {\n    return \u003cRoute /\u003e;\n  }\n}\n```\n\n### Types\n\n#### IRoute\n\n路由配置项。\n\n场景应用：定义 \u003cBrowserRouter /\u003e 组件的 routes 属性。\n\n```tsx\nimport { BrowserRouter } from \"pure-react-router\";\n\nconst routes: IRoute[] = [\n  {\n    path: \"/home\",\n    component: Home,\n  },\n  {\n    path: \"/about\",\n    component: About,\n  },\n  {\n    path: \"/\",\n    component: Home,\n  },\n];\n\nexport const App = () =\u003e {\n  return (\n    \u003cBrowserRouter routes={routes} basename=\"/webapp\"\u003e\n      \u003cRoute /\u003e\n    \u003c/BrowserRouter\u003e\n  );\n};\n```\n\n## 最佳实践\n\n### 路由懒加载\n\n`pure-react-router` 支持路由懒加载，只需将路由配置中的 component 属性的声明方式改为 lazy 函数即可。\n\n**要注意的是，使用 lazy 加载组件后，在 `\u003cRoute /\u003e` 组件的外层需要使用 `Suspense` 组件包裹，否则会出现运行时报错。**\n\n```tsx\nimport { lazy, Suspense } from 'react';\n\nconst routes = [\n  {\n    path: \"/dashboard\",\n    component: lazy(() =\u003e import('./Dashboard')),\n    // 支持路由级加载状态\n    loading: \u003cDashboardSkeleton /\u003e\n  }\n];\n\nfunction App() {\n  return (\n    \u003cBrowserRouter routes={routes}\u003e\n      \u003cSuspense fallback={\u003cGlobalLoader /\u003e}\u003e\n        \u003cRoute /\u003e\n      \u003c/Suspense\u003e\n    \u003c/BrowserRouter\u003e\n  );\n}\n\n```\n\n### 类型安全\n\n`pure-react-router` 提供了完整的类型定义支持，你可以在项目中直接使用。\n\n```tsx\nimport type { IRoute } from 'pure-react-router';\n\n// 类型化路由配置\nconst routes: IRoute[] = [\n  {\n    path: \"/user/:id\",\n    component: UserPage,\n  }\n];\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flexmin0412%2Fpure-react-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flexmin0412%2Fpure-react-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flexmin0412%2Fpure-react-router/lists"}