跳到主要内容

React 路由

在单页面应用(SPA)中,页面导航主要通过路由(Routing)来实现。React 生态中最流行的路由库是 react-router-dom


1. 基础用法

React Router 提供三个核心组件:BrowserRouterRoutesRoute。要在 Docusaurus 实时演示中观察效果,我们使用 MemoryRouter

实时编辑器
function App() {
  const Home = () => <h2>🏠 首页</h2>;
  const About = () => <h2>ℹ️ 关于我们</h2>;

  return (
    <MemoryRouter initialEntries={["/"]}>
      <nav style={{ display: 'flex', gap: '20px', padding: '10px', background: '#e2e8f0' }}>
        <Link to="/">首页</Link>
        <Link to="/about">关于</Link>
      </nav>

      <div style={{ padding: '20px' }}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </div>
    </MemoryRouter>
  );
}

render(<App />);
结果
Loading...

2. 嵌套路由

通过并在子路由中使用 Outlet 作为占位符,可以实现多层级的页面嵌套布局。

实时编辑器
const Layout = () => (
  <div style={{ border: '2px solid #2563eb', padding: '10px' }}>
    <header><h1>我的网站</h1></header>
    <nav style={{ display: 'flex', gap: '10px' }}>
      <Link to="/">首页</Link>
      <Link to="/products">产品列表</Link>
    </nav>
    <hr />
    <main>
      <Outlet />
    </main>
  </div>
);

const Products = () => <h3>📦 产品详情页面</h3>;
const Home = () => <h3>🏚 首页内容</h3>;

function App() {
  return (
    <MemoryRouter initialEntries={["/"]}>
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="products" element={<Products />} />
        </Route>
      </Routes>
    </MemoryRouter>
  );
}

render(<App />);
结果
Loading...

3. 编程式导航

除了 <Link> 标签,你还可以使用 useNavigate 钩子在代码中执行跳转(如登录成功后)。

实时编辑器
function LoginPage() {
  const navigate = useNavigate();

  const handleLogin = () => {
    alert("登录成功!点击确认后即将跳转...");
    navigate("/dashboard");
  };

  return (
    <div style={{ padding: '20px' }}>
      <h3>登录页面</h3>
      <button onClick={handleLogin}>登录</button>
    </div>
  );
}

const Dashboard = () => <h3>📊 仪表盘</h3>;

function App() {
  return (
    <MemoryRouter initialEntries={["/"]}>
      <Routes>
        <Route path="/" element={<LoginPage />} />
        <Route path="/dashboard" element={<Dashboard />} />
      </Routes>
    </MemoryRouter>
  );
}

render(<App />);
结果
Loading...

4. 获取参数 (useParams)

用于动态路由,如 /user/123

实时编辑器
function UserProfile() {
  const { id } = useParams();
  const location = useLocation();

  return (
    <div>
      <p>正在查看用户 ID: <strong>{id}</strong></p>
      <p>当前全路径: {location.pathname}</p>
    </div>
  );
}

function UserList() {
  return (
    <MemoryRouter initialEntries={["/user/admin"]}>
      <nav>
        <Link to="/user/1">用户 1</Link> | <Link to="/user/2">用户 2</Link>
      </nav>
      <Routes>
        <Route path="/user/:id" element={<UserProfile />} />
      </Routes>
    </MemoryRouter>
  );
}

render(<UserList />);
结果
Loading...

小结

  1. MemoryRouter/BrowserRouter:包装应用的主容器。
  2. Routes/Route:定义路径与组件的映射关系。
  3. Link/useNavigate:实现页面跳转(声明式/编程式)。
  4. Outlet:用于嵌套布局的子组件渲染占位符。
  5. useParams:提取 URL 中的参数。