在react中的路由实现路由守卫

  1. 关于react-router
  2. 关于路由守卫
  3. 做法
    1. Context的创建
    2. Provider组件的创建
    3. 使用数据
    4. 路由守卫组件的整体
  4. 一道面试题

路由守卫其实是vue提供的一系列关于某个路由的预先判断, 是一系列钩子函数. 但是在react中并没有这个东西, 也没有查到很好的第三方库, 因此这里结合Provider和Context, 在react中实现路由守卫. 这个功能在前端中主要用来验证用户是否处于登录状态, 并以此来限制用户并将访问非法路由的用户强制跳转到登录页面.

而在此基础上, 会重新开始整理react路由的知识, 并详细解释下面是如何将路由守卫封装成一个组件(或者说组件皮)

关于react-router

首先,react是不存在路由的, 想要尝试使用路由就要使用第三方库, 下载指令为

1
npm -i react-router-dom

下载完成以后就可以使用这种话方式完成路由的布置

1
import { BrowserRouter, Routes,Route } from 'react-router-dom';

在浏览器端, 主要使用这几个作为我们主要的钩子, 他们的具体使用方式如下图所示, 在确定某个路由是跳转到某个组件的时候, 我们套上一层自治的路由守卫

1
2
3
4
5
6
7
8
<BrowserRouter>
<Routes>
<Route path='/' element={<Home/>} />
<Route path='/login' element={<Login/>} />
<Route path='/about' element={<ProtectedRouter Component={()=><Chat/>}/>}/>
<Route path='/about' element={<ProtectedRouter Component={()=><About/>}/>}/>
</Routes>
</BrowserRouter>

剩下的可以直接问gpt了

关于路由守卫

路由守卫在本文中情况是这样的:

有些路由需要用户登陆以后才能会跳转, 但是对于路由应用, 使用url跳转也是一个很常见的漏洞, 因此需要做的是: 当用户导航到一个非法路由(或暂时非法的路由), 强制用户跳转到某个页面

路由守卫是我们的一个自制类, Component属性是我们预留的接口,用来盛放真正的组件. 而路由首位包裹一层的目的就是,当用户跳转这个路由的时候, 根据用户目前的登陆状态, 从而确定用户是应该按照需求正常跳转到Component中,还是说需要强制跳转到其他地方. 将其封装为一个统一的组件, 就方便了所有想要判断是否在登录的组件,实现复用

主要使用Provider,Context以及Navigate标签实现

做法

Context的创建

使用createContext创建一个Context,并且允许外界访问

1
2
3
import { createContext } from 'react';

export const AuthContext = createContext();
Provider组件的创建

然后根据已经创建出的AuthContext(起这个名字是因为后续我们需要用这个上下文内容获取登录鉴权信息), 创建一个provider组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export const AuthProvider = ({ children }) => {
//鉴权状态
const [isLoggedIn, setIsLoggedIn] = useState(false);

const login = () => {
setIsLoggedIn(true);
};

const logout = () => {
setIsLoggedIn(false);
};

return (
<AuthContext.Provider value={{ isLoggedIn,login, logout }}>
{children} //这里代表的是核心其他组件
</AuthContext.Provider>
);
};

在这个组件中, 创建这样一个需要全局读取的数据, 一个鉴权数值, 以及开关. 关于这个代码其实有话要讲, 具体使用这个组件的情形是这样的, children可以理解为vue中的slot, 这样方便我们把根组件包裹住,方便每一个组件都能拿到数据

1
2
3
4
5
6
7
8
9
10
11
12
13
import { AuthProvider } from './Auth';

function App() {
return (
<AuthProvider>
<BrowserRouter>
...........................................
</BrowserRouter>
</AuthProvider>
);
}
export default App;

使用数据

使用的时候, 在useContext的钩子中直接引入我们一开始创建的context即可

1
const { isLoggedIn,login, logout  } = useContext(AuthContext); 

路由守卫组件的整体
1
2
3
4
5
6
7
8
9
10
11
12
13
import { useContext } from 'react';
import { Navigate } from 'react-router-dom';
import { BrowserRouter, Routes,Route } from 'react-router-dom';
import { AuthContext } from '../Auth';

const ProtectedRouter = ({Component}) => { //传进来的对象以及其他的属性

const { isLoggedIn } = useContext(AuthContext); //获取登录对象的方式就是这个
//一旦没有登录就会自动跳转到
return (
isLoggedIn ? <Component/> : <Navigate to={{ pathname: '/login' }} />
);
};

其实总结起来就是先创建上下文Context,然后根据这个上下文创建Provider, 再使用useContext函数获取数据并进行修改即可.

另外注意在代码中,如果传递数据像保证是传递原本的情况,就试着使用箭头函数来是实现传递,不然可能会发生把组件变成对象这种情况的发生.

一道面试题

问: 如果在前端维持用户的权限(登陆状态)

一种最朴素的实验思路就是, 将用户的登录登陆以后, 后端发来信息存在缓存中,遇到一些需要权限的路由地址, 可以直接检查当前用户在客户端缓存内的信息是否为符合要求的权限 另一种不涉及浏览器缓存的, 就是使用Provider和Context来实现全局可控的状态


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 xranudvilas@gmail.com

💰

×

Help us with donation