react-router实现类似vue-router中befor
2021-05-23 本文已影响0人
_stan
react-router中并没有vue-router的路由导航守卫(如beforeEach)等api。
具体原因,作者已经在github上做出了回答
意思是您可以在渲染功能中执行此操作。JSX不需要API,因为它更灵活。
在react中可以使用高阶组件hoc在渲染route组件之前判断登录状态
App.tsx
import React from 'react'
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'
import { AuthButton, PrivateRoute } from './components'
import RootProvider from './RootProvider'
import { Home, Login, User } from './pages'
const App: React.FC = () => {
return (
<RootProvider>
<Router>
<AuthButton />
<ul>
<li><Link to="/home">home</Link></li>
<li><Link to="/user">user</Link></li>
</ul>
<Switch>
<PrivateRoute path={'/home'}>
<Home />
</PrivateRoute>
<PrivateRoute path={'/user'}>
<User />
</PrivateRoute>
<Route path={'/login'} component={Login} />
</Switch>
</Router>
</RootProvider>
)
}
export default App
PrivateRoute是一个高阶组件,主要作用是判断登录状态,如果没有登录则跳转到登录页面。
PrivateRoute.tsx
import React from 'react'
import { useAuth } from '../../RootProvider'
import { Route, Redirect, RouteProps } from 'react-router-dom'
export const PrivateRoute: React.FC<RouteProps> = ({ children, ...props }) => {
const { user } = useAuth()
return (
<Route
{...props}
render={({ location }) =>
user ? (
children
) : (
<Redirect
to={{
pathname: '/login',
state: { from: location }
}}
/>
)
}
/>
)
}
全局的context
import React, { createContext, Context, useContext } from 'react'
import { useLogin } from './hooks'
const AuthContext: Context<any> = createContext({})
const RootProvider: React.FC = ({ children }) => {
const auth = useLogin()
return (
<AuthContext.Provider value={auth}>
{children}
</AuthContext.Provider>
)
}
export const useAuth = () => useContext(AuthContext)
export default RootProvider
使用到的hook
import { useState } from 'react'
export const useLogin = () => {
const [user, setUser] = useState<string | null>(null)
const login = cb => {
setUser('lin')
cb()
}
const logout = cb => {
setUser(null)
cb()
}
return {
user,
login,
logout
}
}
最后的效果:
-
没有登录 点击跳转home和user页面都会跳转到登录页面
-
登录后可以正常访问user和home页面