我正在尝试创建专用路由并验证登录名,我想执行API调用,它需要异步处理,但是不能在专用路由组件内使用异步处理。因此尝试使用useEffect(),但它也显示了自身的局限性,存在以下问题:
我的简单要求是拥有两条路由,分别是“公共”和“私有”,并验证用户是否登录。它需要执行API调用以检查用户是否具有有效的会话。
如果我能在React中学习,那么任何人都可以纠正我的代码或指导如何修复它会很有帮助。提前谢谢。
以下是我的代码: Router.js
if rv is None:
verifyToken.js
import React, {Suspense, lazy, useEffect, useState } from "react"
import { Router, Switch, Route, Redirect } from "react-router-dom"
import { history } from "./history"
import { connect } from "react-redux"
import Spinner from "./components/@project/spinner/Loading-spinner"
import { ContextLayout } from "./utility/context/Layout"
import verifyToken from './authServices/verifyToken'
// Route-based code splitting
const dashboard = lazy(() => import("./views/Dashboards/Dashboard"))
const profile = lazy(() => import("./views/Profile"))
//error Pages
const error404 = lazy(() => import("./views/Misc/error/404"))
const error500 = lazy(() => import("./views/Misc/error/500"))
const authorized = lazy(() => import("./views/Misc/NotAuthorized"))
const maintenance = lazy(() => import("./views/Misc/Maintenance"))
//AuthorizedPages
const Login = lazy(() => import("./views/authentication/login/Login"))
const forgotPassword = lazy(() => import("./views/authentication/ForgotPassword"))
const lockScreen = lazy(() => import("./views/authentication/LockScreen"))
const register = lazy(() => import("./views/authentication/register/Register"))
// Set Layout and Component Using App Route
function useVerified(auth, path){
const [verified, setVerifiedValue] = useState();
useEffect(() => {
const doVerify = async () => {
setVerifiedValue(await verifyToken(auth))
}
doVerify()
}, [path])
return verified;
}
const RouteConfig = ({ component: Component, fullLayout, user, auth, ...rest}) => {
const path = ({...rest}.path)
const verified = useVerified(auth, path);
return <Route
{...rest}
render={props => {
return (
<ContextLayout.Consumer>
{context => {
let LayoutTag =
fullLayout === true
? context.fullLayout
: context.VerticalLayout
return (auth.values !== undefined && auth.values.isSignedIn && verified) ? (
<LayoutTag {...props} permission={user}>
<Suspense fallback={<Spinner />}>
<Component {...props}></Component>
</Suspense>
</LayoutTag>
) : (
<context.fullLayout {...props} permission={user}>
<Suspense fallback={<Spinner />}>
<Login {...props} />
</Suspense>
</context.fullLayout>
)
}}
</ContextLayout.Consumer>
)
}}
/>
}
const mapStateToProps = state => {
return {
user: state.auth.login.userRole,
auth: state.auth.login
}
}
const AppRoute = connect(mapStateToProps)(RouteConfig)
const PublicRoute = ({ component: Component, fullLayout, ...rest }) => (
<Route {...rest} render={() => {
return (
<ContextLayout.Consumer>
{context => {
let LayoutTag =
fullLayout === true
? context.fullLayout
: context.VerticalLayout
return (
<LayoutTag>
<Suspense fallback={<Spinner />}>
<Component/>
</Suspense>
</LayoutTag>
)
}}
</ContextLayout.Consumer>
)
}}
/>
)
class AppRouter extends React.Component {
render() {
return (
// Set the directory path if you are deploying in sub-folder
<Router history={history}>
<Switch>
<PublicRoute exact path="/login" component={Login} fullLayout />
<PublicRoute exact path="/" component={Login} fullLayout />
<PublicRoute path="/register" component={register} fullLayout />
<PublicRoute path="/forgot-password" component={forgotPassword} fullLayout />
<AppRoute path="/dashboard" component={dashboard} />
<AppRoute path="/profile" component={profile} />
<AppRoute path="/404" component={error404} fullLayout />
<AppRoute path="/500" component={error500} fullLayout />
<AppRoute path="/not-authorized" component={authorized} fullLayout />
<AppRoute path="/maintenance" component={maintenance} fullLayout />
<AppRoute component={error404} fullLayout />
</Switch>
</Router>
)
}
}
export default AppRouter
API呼叫代码
import jwt from 'jsonwebtoken';
import { refreshToken } from "../redux/actions/auth/loginActions"
const verifyToken = async props => {
if('accessToken' in props && 'accessToken' in props.accessToken){
if (props.accessToken.accessToken !== undefined && props.accessToken.accessToken !== null) {
if (assertAlive(jwt.decode(props.accessToken.accessToken))) {
const verified = await refreshToken(props)
if (verified){
return true
} else {
return false
}
} else {
return false
}
}else
return false
}else
return false
}
function assertAlive (decoded) {
const now = Date.now().valueOf() / 1000
if (typeof decoded.exp !== 'undefined' && decoded.exp < now) {
//throw new Error(`token expired: ${JSON.stringify(decoded)}`)
return false
}
if (typeof decoded.nbf !== 'undefined' && decoded.nbf > now) {
//throw new Error(`token not yet valid: ${JSON.stringify(decoded)}`)
return false
}
return true
}
export default verifyToken;