返回首页

说说你对 React Router 的理解?常用的 Router 组件有哪些?

问题解析(面试官考察点)

面试官通过此问题主要考察:

  • 对前端路由概念的理解程度
  • 对 React Router 核心功能的掌握
  • 对常用 Router 组件的熟悉程度和使用场景
  • 对单页应用(SPA)路由机制的理解

核心概念(基础知识点)

什么是 React Router

React Router 是 React 生态系统中用于实现路由功能的库,它可以在不刷新页面的情况下,根据 URL 的变化来切换显示不同的组件内容,实现单页应用(SPA)的页面导航。

React Router 的核心包

  • react-router: 实现了路由的核心功能
  • react-router-dom: 基于 react-router,加入了在浏览器运行环境下的功能
  • react-router-native: 基于 react-router,加入了 react-native 运行环境下的功能
  • react-router-config: 用于配置静态路由的工具库

详细解答(代码示例)

常用的 Router 组件

1. BrowserRouter / HashRouter

作为路由的容器组件,包裹整个应用:

import { BrowserRouter as Router } from "react-router-dom";

function App() {
  return (
    <Router>
      <main>
        <nav>
          <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/about">About</a></li>
            <li><a href="/contact">Contact</a></li>
          </ul>
        </nav>
      </main>
    </Router>
  );
}

2. Route 组件

用于路径匹配和组件渲染:

import { BrowserRouter as Router, Route } from "react-router-dom";

function App() {
  return (
    <Router>
      <main>
        {/* 使用 component 属性 */}
        <Route path="/" exact component={Home} />

        {/* 使用 render 属性 */}
        <Route path="/welcome" render={() => <h1>Welcome!</h1>} />

        {/* 使用 children 属性 */}
        <Route path="/dashboard">
          <Dashboard />
        </Route>
      </main>
    </Router>
  );
}

Route 组件常用属性:

  • path: 匹配的路径
  • component: 匹配成功后渲染的组件
  • render: 匹配成功后渲染的内容(函数形式)
  • exact: 开启精确匹配

3. Link / NavLink 组件

用于页面跳转,替代传统的 <a> 标签:

import { Link, NavLink } from "react-router-dom";

function Navigation() {
  return (
    <nav>
      {/* 基础链接 */}
      <Link to="/">首页</Link>
      <Link to="/about">关于</Link>

      {/* 带活跃样式的链接 */}
      <NavLink to="/" exact activeStyle={{ color: "red" }}>
        首页
      </NavLink>
      <NavLink to="/about" activeClassName="active">
        关于
      </NavLink>
    </nav>
  );
}

4. Switch 组件

用于包裹多个 Route,只渲染第一个匹配的组件:

import { Switch, Route } from "react-router-dom";

function App() {
  return (
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/profile" component={Profile} />
      <Route path="/:userid" component={User} />
      <Route component={NoMatch} /> {/* 404 页面 */}
    </Switch>
  );
}

5. Redirect 组件

用于路由重定向:

import { Redirect } from "react-router-dom";

function About({ match: { params: { name } } }) {
  return (
    <>
      {name !== "tom" ? <Redirect to="/" /> : null}
      <h1>About {name}</h1>
    </>
  );
}

6. Hooks API

React Router v5+ 提供的 Hooks:

import { useHistory, useParams, useLocation } from "react-router-dom";

function Contact() {
  const history = useHistory();
  const { id } = useParams();
  const { pathname } = useLocation();

  return (
    <div>
      <h1>Contact</h1>
      <p>Current URL: {pathname}</p>
      <p>ID: {id}</p>
      <button onClick={() => history.push("/")}>
        Go to home
      </button>
      <button onClick={() => history.goBack()}>
        Go back
      </button>
    </div>
  );
}

参数传递方式

动态路由参数

// 定义路由
<Route path="/detail/:id" component={Detail}/>

// 获取参数
function Detail({ match }) {
  const { id } = match.params;
  return <div>Detail ID: {id}</div>;
}

// 或使用 useParams
import { useParams } from "react-router-dom";
function Detail() {
  const { id } = useParams();
  return <div>Detail ID: {id}</div>;
}

Query 参数

// 跳转时传递
<Link to="/detail?name=why&age=18">详情</Link>

// 获取参数
import { useLocation } from "react-router-dom";

function Detail() {
  const location = useLocation();
  const searchParams = new URLSearchParams(location.search);
  const name = searchParams.get("name");
  const age = searchParams.get("age");

  return <div>Name: {name}, Age: {age}</div>;
}

State 传参

// 跳转时传递
<Link to={{
  pathname: "/detail",
  state: { name: "kobe", age: 30 }
}}>详情</Link>

// 获取参数
import { useLocation } from "react-router-dom";

function Detail() {
  const location = useLocation();
  const { name, age } = location.state || {};

  return <div>Name: {name}, Age: {age}</div>;
}

深入理解(原理剖析)

前端路由的本质

前端路由的本质是 URL 与 UI 之间的映射关系。当 URL 发生变化时,页面的显示结果根据 URL 的变化而变化,但页面不会刷新。

React Router 的工作原理

  1. History 管理: React Router 通过封装浏览器原生的 History API(history 模式)或监听 hashchange 事件(hash 模式)来管理 URL 变化

  2. Context 传递: Router 组件通过 React Context 将 location、history 等数据传递给子组件

  3. 路径匹配: Route 组件通过 path-to-regexp 等库将当前路径与配置的 path 进行匹配

  4. 组件渲染: 匹配成功后,渲染对应的组件内容

HashRouter vs BrowserRouter

特性 HashRouter BrowserRouter
URL 形式 /#/path /path
实现原理 hashchange 事件 History API
兼容性 更好(IE8+) 现代浏览器
服务端配置 不需要 需要配置 fallback
SEO 较差 较好

最佳实践

1. 路由配置抽离

// routes.js
const routes = [
  { path: "/", exact: true, component: Home },
  { path: "/about", component: About },
  { path: "/users/:id", component: User },
  { component: NotFound }
];

// App.js
import { Route, Switch } from "react-router-dom";
import routes from "./routes";

function App() {
  return (
    <Switch>
      {routes.map((route, index) => (
        <Route key={index} {...route} />
      ))}
    </Switch>
  );
}

2. 路由懒加载

import { lazy, Suspense } from "react";
import { Route, Switch } from "react-router-dom";

const Home = lazy(() => import("./pages/Home"));
const About = lazy(() => import("./pages/About"));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Suspense>
  );
}

3. 路由守卫实现

import { Route, Redirect } from "react-router-dom";

function PrivateRoute({ component: Component, isAuth, ...rest }) {
  return (
    <Route
      {...rest}
      render={(props) =>
        isAuth ? (
          <Component {...props} />
        ) : (
          <Redirect to={{ pathname: "/login", state: { from: props.location } }} />
        )
      }
    />
  );
}

4. 使用 useHistory 替代 withRouter

// 推荐:使用 Hooks
import { useHistory } from "react-router-dom";

function MyComponent() {
  const history = useHistory();
  const handleClick = () => {
    history.push("/target");
  };
  return <button onClick={handleClick}>Go</button>;
}

面试要点

  1. React Router 是什么: 用于 React 应用的路由管理库,实现 SPA 无刷新页面切换

  2. 常用组件:

    • BrowserRouter/HashRouter: 路由容器
    • Route: 路径匹配和组件渲染
    • Link/NavLink: 导航链接
    • Switch: 只渲染第一个匹配的 Route
    • Redirect: 重定向
  3. Hooks API:

    • useHistory: 获取 history 对象
    • useParams: 获取路由参数
    • useLocation: 获取当前 location
  4. 两种模式区别:

    • Hash 模式使用 URL hash,兼容性更好
    • History 模式使用 History API,URL 更美观,需要服务端配置
  5. 参数传递: 动态路由参数、Query 参数、State 参数