本节摘要:Solid Router 的特别之处不是语法,而是底座:路由参数、查询串都是信号,路由切换不重渲染组件树,只是依赖图上的值变化。本节从路由表搭起,逐项对照 React Router 的路由配置、动态段、嵌套布局、懒加载与导航 API,并画出一次带数据加载的路由切换时序。
某天产品提需求:后台系统要加一个"订单详情"页,从列表页点进去,地址带上订单号,刷新后直达,详情数据按订单号加载。这个需求里藏着路由器的全部核心职责:URL 解析、动态段、嵌套布局、数据触发、导航。两框架各写一遍,差异自然浮出来。
React Router(v6 风格)的路由对象树:
createBrowserRouter([ { path: "/", element: <Layout />, children: [ { index: true, element: <Home /> }, { path: "orders", element: <Orders /> }, { path: "orders/:orderId", element: <OrderDetail /> }, ], }, ]);
Solid Router 的等价结构:
import { Router, Route } from "@solidjs/router"; <Router root={Layout}> <Route path="/" component={Home} /> <Route path="/orders" component={Orders} /> <Route path="/orders/:orderId" component={OrderDetail} /> </Router>
布局的承载方式不同:React Router 用 element 加 children 嵌套,子路由渲染进 <Outlet />;Solid Router 用 root 或父级 Route 的组件接收 props.children——第 3 章讲过,这个 children 是响应式的,路由切换时它内部换入换出的就是子页面组件。动态段写法一致(:orderId),懒加载也一致:component={lazy(() => import("./OrderDetail"))},与第 2 章提过的 lazy 原语配合。
详情页里读参数,React 用 useParams 返回普通对象,值随重渲染更新;Solid 用同名钩子返回信号:
import { useParams, useNavigate, useSearchParams } from "@solidjs/router"; import { createResource } from "solid-js"; function OrderDetail() { const params = useParams(); // params.orderId 是信号 const [search, setSearch] = useSearchParams(); // 查询串读写也是信号 const navigate = useNavigate(); const [order] = createResource(() => params.orderId, fetchOrder); // 来源信号变化 → 自动重新请求,路由跳转即数据刷新 return ( <div> <p>订单 {params.orderId},标签页 {search.tab ?? "基础信息"}</p> <button onClick={() => navigate("/orders")}>返回列表</button> <button onClick={() => setSearch({ tab: "物流" })}>看物流</button> </div> ); }
这段代码浓缩了三个对位差异。差异一:createResource 的来源直接就是路由参数——URL 变化触发重新请求,中间不需要 useEffect 监听 props.match 的样板。差异二:查询串读写对称,setSearch 改的 search.tab 会同步进地址栏,任何读它的绑定自动更新;React 里这要 navigate 加 state 两件事配合。差异三:没有"路由变化引发整树重渲染"这回事——params.orderId 是信号,谁读了谁更新,侧边栏里恰好也显示订单号的地方会独立更新,其余界面纹丝不动。

| 能力 | React Router | Solid Router | 备注 |
|---|---|---|---|
| 路由声明 | 路由对象树或 JSX | Route 组件或对象 |
形态相近 |
| 布局 | Outlet |
props.children |
响应式通道 |
| 动态段 | useParams 返回对象 |
返回信号 | 可直接作资源来源 |
| 查询串 | useSearchParams |
同名,读写信号 | 语义对称 |
| 编程导航 | useNavigate |
同名 | 传字符串或对象 |
| 懒加载 | lazy + Suspense |
lazy + Suspense |
原语复用 |
| 链接 | Link |
A |
支持 active 态类名 |
| 未匹配 | errorElement 或 catch-all |
fallback 分支 | 写法略异 |
A 组件值得一句:它对标 React Router 的 Link,额外内建了"当前路径匹配时加激活类名"的能力,导航高亮不用再手写 pathname 比对。
⚠️ 迁移时最容易写错的是"把 params 当普通对象解构"——
const { orderId } = useParams()拿到的是一次快照,路由再变就不会更新了。与 props 同一道坑:保持params.orderId的访问形式,响应式才不断流。
下一章上探全栈层——SolidStart 如何在路由约定之上补齐服务端渲染与部署。