MST

星途 面试题库

面试题:React路由导航守卫的原理及实现

说明React路由中导航守卫的作用是什么,以及在React Router库中如何实现类似导航守卫的功能,比如在进入某路由前进行权限验证。请详细描述实现思路及关键代码逻辑。
43.0万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

导航守卫的作用

在 React 路由中,导航守卫类似于 Vue 路由中的导航守卫,主要用于在路由切换过程中执行一些特定逻辑。其主要作用如下:

  1. 权限验证:在进入特定路由之前,检查用户是否具备相应权限,如是否已登录、是否具有特定角色等,以决定是否允许用户访问该路由。
  2. 数据预处理:在进入路由前,提前获取或处理该路由所需的数据,例如在进入用户详情页前,先从服务器获取用户详细信息。
  3. 页面状态管理:根据当前应用状态或用户操作,决定是否允许路由切换,例如在用户编辑表单未保存时,提示用户是否保存后再进行路由切换。

在 React Router 库中实现类似导航守卫功能(以权限验证为例)的思路

  1. 创建高阶组件(HOC):通过创建一个高阶组件,将权限验证逻辑封装在其中。这个高阶组件接收一个组件作为参数,并返回一个新的带有权限验证逻辑的组件。
  2. 在高阶组件中进行权限验证:在高阶组件内部,根据应用的权限管理机制(如检查 Redux 中的用户状态、localStorage 中的登录信息等)来判断用户是否有权限访问目标路由。
  3. 决定路由导航行为:如果用户有权限,正常渲染传入的组件;如果用户没有权限,则可以重定向到特定页面(如登录页)或显示提示信息。

关键代码逻辑示例

假设使用 React Router v5 且结合 Redux 管理状态,以下是实现权限验证导航守卫的代码示例:

  1. 安装依赖 确保项目中安装了 react-router-domredux 等相关依赖。

  2. 创建高阶组件

import React from 'react';
import { Redirect, Route } from'react-router-dom';
import { useSelector } from'react-redux';

const withAuth = (WrappedComponent) => {
  return (props) => {
    const isAuthenticated = useSelector(state => state.auth.isAuthenticated);
    return (
      <Route {...props}>
        {isAuthenticated? (
          <WrappedComponent {...props} />
        ) : (
          <Redirect to="/login" />
        )}
      </Route>
    );
  };
};

export default withAuth;
  1. 使用高阶组件
import React from'react';
import { BrowserRouter as Router, Routes } from'react-router-dom';
import Dashboard from './components/Dashboard';
import Login from './components/Login';
import withAuth from './hoc/withAuth';

const App = () => {
  return (
    <Router>
      <Routes>
        <Route path="/login" element={<Login />} />
        <Route path="/dashboard" element={withAuth(Dashboard)} />
      </Routes>
    </Router>
  );
};

export default App;

在上述代码中:

  • withAuth 高阶组件接收一个组件 WrappedComponent,在内部通过 useSelector 获取 Redux 状态中的 isAuthenticated 字段判断用户是否已认证。
  • 如果已认证,则渲染传入的 WrappedComponent;否则,重定向到 /login 路径。
  • App 组件中,对 /dashboard 路由使用 withAuth 高阶组件来实现进入该路由前的权限验证。

如果使用 React Router v6,实现方式有所不同:

import React from'react';
import { createBrowserRouter, RouterProvider } from'react-router-dom';
import Dashboard from './components/Dashboard';
import Login from './components/Login';
import { useSelector } from'react-redux';

const requireAuth = ({ request }) => {
  const isAuthenticated = useSelector(state => state.auth.isAuthenticated);
  if (!isAuthenticated) {
    return {
      redirectTo: '/login',
      state: { from: request.url }
    };
  }
};

const router = createBrowserRouter([
  {
    path: '/login',
    element: <Login />
  },
  {
    path: '/dashboard',
    element: <Dashboard />,
    loader: requireAuth
  }
]);

const App = () => {
  return <RouterProvider router={router} />;
};

export default App;

在 React Router v6 中,通过 createBrowserRouter 创建路由,并使用 loader 函数进行权限验证。如果未通过验证,loader 函数返回一个包含 redirectTo 字段的对象,实现重定向。