ReactJS:如果在承诺解决后进行身份验证,则呈现私有路由



我有这个PrivateRoute功能组件,它决定渲染组件,该组件作为他有权访问的用户的道具,根据他的身份验证或重定向到未经授权的路由。

isValidToken是一个异步函数,检查用户是否有有效的令牌,并返回一个布尔值,该布尔值分配给isUserLogged.so 当我在钩子中调用此函数时useEffect它等待函数解析,但在完成重定向之前发生。 那么我如何等待它解析并根据该值渲染

,然后再解决承诺?
import React, { useState, useEffect } from "react";
import { Route, Redirect } from "react-router-dom";
import isValidToken from "../utils/isValidToken";
const ProtectedRoute = ({ component: Comp, path, redirectto, ...rest }) => {
const [isloggedin, setloggedin] = useState(false);
useEffect(() => {
(async function() {
const isUserLogged = await isValidToken();
setloggedin(isUserLogged);
})();
}, []);
return (
<Route
path={path}
{...rest}
render={props => {
return isloggedin ? (
<Comp {...props} />
) : (
<Redirect to={redirectto} />
// <h1>404 error</h1>
);
}}
/>
);
};
export default ProtectedRoute;

为了避免过早的重定向,你的组件需要考虑承诺的"挂起状态"(这是在你的异步函数调用后面(。

在挂起(或"正在加载"(状态期间,通常会呈现类似加载微调器的内容,以向用户指示应用正忙。关键是在解决(或拒绝(承诺之前不要呈现<Comp /><Redirect />组件:

import React, { useState, useEffect } from "react";
import { Route, Redirect } from "react-router-dom";
import isValidToken from "../utils/isValidToken";
const ProtectedRoute = ({ component: Comp, path, redirectto, ...rest }) => {
/* Track the state of your app instead. Start with a "loading" state */
const [state, setState] = useState('loading');
useEffect(() => {
(async function() {
try {
/* Update effect logic to track correct state */
const isUserLogged = await isValidToken();
setState(isUserLogged ? 'loggedin' : 'redirect');
}
catch {
setState('redirect');
}
})();
}, []);

/* If in loading state, return loading message while waiting for 
isValidToken to complete */
if(state === 'loading') {
return <div>Loading..</div>
}
return (
<Route
path={path}
{...rest}
{/* Decide what component to render based on state */
render={props => ((state === 'loggedin') ? 
<Comp {...props} /> : 
<Redirect to={redirectto} />) }
/>
);
};
export default ProtectedRoute;

试试这个:

import React, { useState, useEffect } from "react";
import { Route, Redirect } from "react-router-dom";
import isValidToken from "../utils/isValidToken";
const ProtectedRoute = ({ component: Comp, path, redirectto, ...rest }) => {
const [isloggedin, setloggedin] = useState(false);
const [redirectTo, setRedirectTo] = useState(null);
useEffect(() => {
(async function() {
const isUserLogged = await isValidToken();
setloggedin(isUserLogged);
setRedirectTo('/route');
})();
}, []);
if (redirectTo && isloggedin) {
return <Redirect to={redirectTo} />
}
return (
<Route
path={path}
{...rest}
render={props => <Comp {...props} />}
/>
);
};
export default ProtectedRoute;

最新更新