路由

React Router / Next.js

推荐

Next.js

如果是新项目,它不仅能切换页面,还具备利于搜索排名的结构和发布网站的机制。本站也是用 Next.js 做的

比较效果

用每个库做了同样的东西,动手试试看。

React Router

比较代码

修改代码,右边的预览会跟着变化。

import { MemoryRouter, Routes, Route, Link, useParams, useLocation } from "react-router"

const items = [
  { slug: "apple", name: "苹果", price: 10.5 },
  { slug: "orange", name: "橘子", price: 7 },
]

// 样式(不是这个演示的重点)
const linkStyle = { color: "#18181b", textDecoration: "none", fontSize: 14 }

function Home() {
  return <h2 style={{ margin: 0, fontSize: 18 }}>首页</h2>
}

function ItemList() {
  return (
    <div>
      <h2 style={{ margin: "0 0 8px", fontSize: 18 }}>商品列表</h2>
      <ul style={{ listStyle: "none", margin: 0, padding: 0 }}>
        {items.map((item) => (
          <li key={item.slug} style={{ padding: "8px 0", borderTop: "1px solid #f4f4f5" }}>
            <Link to={"/items/" + item.slug} style={linkStyle}>
              {item.name} →
            </Link>
          </li>
        ))}
      </ul>
    </div>
  )
}

function ItemDetail() {
  // 取出 URL 中的 :slug 部分(例如 apple)
  const { slug } = useParams()
  const item = items.find((i) => i.slug === slug)

  if (!item) {
    return <p>找不到该商品</p>
  }

  return (
    <div>
      <h2 style={{ margin: 0, fontSize: 18 }}>{item.name}</h2>
      <p style={{ margin: "4px 0 12px", color: "#71717a" }}>¥{item.price.toFixed(2)}</p>
      <Link to="/items" style={linkStyle}>← 返回列表</Link>
    </div>
  )
}

// 显示当前 URL(演示里看不到地址栏)
function CurrentUrl() {
  const location = useLocation()
  return (
    <span style={{ marginLeft: "auto", padding: "2px 8px", borderRadius: 6, background: "#f4f4f5", color: "#71717a", fontSize: 12, fontFamily: "monospace" }}>
      {location.pathname}
    </span>
  )
}

export default function App() {
  return (
    // MemoryRouter:只在演示内部切换 URL(普通网站使用 BrowserRouter)
    <MemoryRouter>
      <div style={{ maxWidth: 360, margin: "0 auto", border: "1px solid #e4e4e7", borderRadius: 12, fontFamily: "system-ui, sans-serif", overflow: "hidden" }}>
        <nav style={{ display: "flex", alignItems: "center", gap: 16, padding: "10px 16px", borderBottom: "1px solid #f4f4f5" }}>
          <Link to="/" style={linkStyle}>首页</Link>
          <Link to="/items" style={linkStyle}>商品列表</Link>
          <CurrentUrl />
        </nav>

        <div style={{ padding: 16 }}>
          {/* URL 与页面的对应表(path = URL,element = 此时显示的页面) */}
          <Routes>
            {/* 访问 "/" 时显示首页 */}
            <Route path="/" element={<Home />} />
            {/* 访问 "/items" 时显示商品列表 */}
            <Route path="/items" element={<ItemList />} />
            {/* 访问 "/items/任意内容" 时显示商品详情(:slug = 这里可以是任何值) */}
            <Route path="/items/:slug" element={<ItemDetail />} />
          </Routes>
        </div>
      </div>
    </MemoryRouter>
  )
}

用 Next.js 实现同样的功能

app/page.tsx → /

export default function Page() {
  return <h2>首页</h2>
}

app/items/page.tsx → /items

import Link from "next/link"
import { items } from "@/data/items"

export default function Page() {
  return (
    <div>
      <h2>商品列表</h2>
      <ul>
        {items.map((item) => (
          <li key={item.slug}>
            <Link href={"/items/" + item.slug}>{item.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  )
}

app/items/[slug]/page.tsx → /items/apple 等

import Link from "next/link"
import { notFound } from "next/navigation"
import { items } from "@/data/items"

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  // 取出 URL 中的 [slug] 部分(例如 apple)
  const { slug } = await params
  const item = items.find((i) => i.slug === slug)

  if (!item) {
    notFound()
  }

  return (
    <div>
      <h2>{item.name}</h2>
      <p>¥{item.price.toFixed(2)}</p>
      <Link href="/items">← 返回列表</Link>
    </div>
  )
}

比较

截至 2026 年 10 月

React Router

官方网站 ↗

特点

为 React 应用加上页面切换功能的库。用代码写一张“这个 URL 显示这个页面”的对照表。页面内容在浏览器中生成

适用场景

给已有的 React 应用添加页面。登录后使用的管理后台等不需要被搜索到的应用

Next.js

推荐官方网站 ↗

特点

用 React 构建网站的框架。文件夹和文件的结构直接就是 URL(app/basics/page.tsx → /basics)。页面在服务器上生成后再发送

适用场景

新建一个希望被搜索到的网站:博客、网店、产品介绍页等