React Router 
1. 什么是 React Router?它的主要作用是什么? 
答案:React Router 是 React 生态系统中最常用的路由库。它允许你在 React 应用中实现动态路由,使得单页应用 (SPA) 能够像多页应用一样工作,而无需重新加载页面。
主要作用:
- 声明式路由定义
- 动态路由匹配
- 嵌套路由和布局
- 历史管理
- 代码分割
2. React Router 的基本组件有哪些?它们的作用是什么? 
答案:React Router 的基本组件包括:
- <BrowserRouter>:使用 HTML5 history API 来保持 UI 和 URL 的同步。
- <Route>:定义路由路径和要渲染的组件。
- <Link>:声明式的导航组件,用于创建链接。
- <Switch>:渲染第一个匹配的- <Route>或- <Redirect>。
- <Redirect>:强制导航到特定位置。
示例:
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
function App() {
  return (
    <Router>
      <div>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
        </nav>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Redirect to="/" />
        </Switch>
      </div>
    </Router>
  );
}3. 如何在 React Router 中实现动态路由? 
答案:动态路由可以通过在路径中使用参数来实现。这些参数可以在组件中通过 props 访问。
示例:
import { BrowserRouter as Router, Route, useParams } from 'react-router-dom';
function UserProfile() {
  let { id } = useParams();
  return <div>User ID: {id}</div>;
}
function App() {
  return (
    <Router>
      <Route path="/user/:id" component={UserProfile} />
    </Router>
  );
}在这个例子中,/user/123 这样的 URL 会匹配 UserProfile 组件,并且 123 会作为 id 参数传递给组件。
4. React Router 中的 <Link> 和普通的 <a> 标签有什么区别? 
答案:<Link> 组件和 <a> 标签的主要区别在于:
- <Link>使用 React Router 的内部机制来处理导航,不会导致整个页面重新加载。
- <Link>会阻止默认的页面刷新行为,而是使用 History API 来更新 URL。
- <Link>可以感知和利用 React Router 的上下文。
示例:
import { Link } from 'react-router-dom';
function Navigation() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  );
}5. 如何在 React Router 中实现路由守卫(Route Guards)? 
答案:React Router 没有内置的路由守卫机制,但我们可以通过创建自定义组件来实现类似的功能。
示例:
import { Route, Redirect } from 'react-router-dom';
function PrivateRoute({ component: Component, isAuthenticated, ...rest }) {
  return (
    <Route
      {...rest}
      render={(props) =>
        isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect to="/login" />
        )
      }
    />
  );
}
function App() {
  const isAuthenticated = checkAuthStatus(); // 假设这个函数检查认证状态
  return (
    <Router>
      <Switch>
        <Route path="/login" component={Login} />
        <PrivateRoute
          path="/dashboard"
          component={Dashboard}
          isAuthenticated={isAuthenticated}
        />
      </Switch>
    </Router>
  );
}这个例子中的 PrivateRoute 组件会检查用户是否已认证,如果没有,则重定向到登录页面。
6. 什么是编程式导航?如何在 React Router 中实现? 
答案:编程式导航是指通过 JavaScript 代码来控制路由跳转,而不是通过点击链接。在 React Router 中,我们可以使用 history 对象来实现编程式导航。
示例:
import { useHistory } from 'react-router-dom';
function NavigateButton() {
  let history = useHistory();
  function handleClick() {
    history.push('/home');
  }
  return (
    <button type="button" onClick={handleClick}>
      Go to Home
    </button>
  );
}在这个例子中,点击按钮会导航到 '/home' 路径。
7. 如何在 React Router 中实现嵌套路由? 
答案:嵌套路由可以通过在父路由组件中定义子路由来实现。
示例:
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
function User() {
  return (
    <div>
      <h2>User</h2>
      <nav>
        <Link to="/user/profile">Profile</Link>
        <Link to="/user/settings">Settings</Link>
      </nav>
      <Switch>
        <Route path="/user/profile" component={Profile} />
        <Route path="/user/settings" component={Settings} />
      </Switch>
    </div>
  );
}
function App() {
  return (
    <Router>
      <Switch>
        <Route path="/user" component={User} />
        <Route path="/" exact component={Home} />
      </Switch>
    </Router>
  );
}在这个例子中,/user/profile 和 /user/settings 是 /user 的子路由。
8. 什么是 React Router 的 withRouter 高阶组件?它有什么用途? 
答案:withRouter 是一个高阶组件,它可以将 React Router 的 history、location 和 match 对象作为 props 传递给被包装的组件。这对于需要访问路由信息但不直接在路由中渲染的组件很有用。
示例:
import { withRouter } from 'react-router-dom';
function MyComponent({ history, location, match }) {
  return (
    <div>
      <p>Current path: {location.pathname}</p>
      <button onClick={() => history.push('/home')}>Go to Home</button>
    </div>
  );
}
export default withRouter(MyComponent);注意:在 React Router v6 中,withRouter 被移除,推荐使用 hooks 如 useHistory、useLocation 和 useParams 来替代。
9. React Router 中的 <Switch> 组件有什么作用? 
答案:<Switch> 组件用于渲染与当前位置匹配的第一个 <Route> 或 <Redirect>。这对于排他性路由很有用,确保只渲染一个路由。
没有 <Switch> 的情况下,所有匹配的路由都会被渲染。使用 <Switch> 可以提高路由的效率和可预测性。
示例:
import { Switch, Route } from 'react-router-dom';
function App() {
  return (
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/:user" component={User} />
      <Route component={NoMatch} />
    </Switch>
  );
}在这个例子中,只有一个路由会被渲染,而且 /:user 不会匹配 /about。
10. 如何在 React Router 中实现路由的懒加载? 
答案:路由的懒加载可以通过 React 的 lazy 和 Suspense 功能结合 React Router 来实现。这可以显著提高应用的性能,特别是对于大型应用。
示例:
import React, { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));
function App() {
  return (
    <Router>
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
        </Switch>
      </Suspense>
    </Router>
  );
}在这个例子中,Home 和 About 组件会在需要时才被加载,而不是在应用启动时就全部加载。Suspense 组件提供了一个加载指示器,在组件加载完成之前显示。