面试题答案
一键面试导航守卫的作用
在 React 路由中,导航守卫类似于 Vue 路由中的导航守卫,主要用于在路由切换过程中执行一些特定逻辑。其主要作用如下:
- 权限验证:在进入特定路由之前,检查用户是否具备相应权限,如是否已登录、是否具有特定角色等,以决定是否允许用户访问该路由。
- 数据预处理:在进入路由前,提前获取或处理该路由所需的数据,例如在进入用户详情页前,先从服务器获取用户详细信息。
- 页面状态管理:根据当前应用状态或用户操作,决定是否允许路由切换,例如在用户编辑表单未保存时,提示用户是否保存后再进行路由切换。
在 React Router 库中实现类似导航守卫功能(以权限验证为例)的思路
- 创建高阶组件(HOC):通过创建一个高阶组件,将权限验证逻辑封装在其中。这个高阶组件接收一个组件作为参数,并返回一个新的带有权限验证逻辑的组件。
- 在高阶组件中进行权限验证:在高阶组件内部,根据应用的权限管理机制(如检查 Redux 中的用户状态、localStorage 中的登录信息等)来判断用户是否有权限访问目标路由。
- 决定路由导航行为:如果用户有权限,正常渲染传入的组件;如果用户没有权限,则可以重定向到特定页面(如登录页)或显示提示信息。
关键代码逻辑示例
假设使用 React Router v5 且结合 Redux 管理状态,以下是实现权限验证导航守卫的代码示例:
-
安装依赖 确保项目中安装了
react-router-dom
和redux
等相关依赖。 -
创建高阶组件
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;
- 使用高阶组件
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
字段的对象,实现重定向。