很抱歉,如果这是我忽略的非常简单的事情,但我正在尝试制作一个组件,它基本上只将某些react路由器路由限制为具有活动令牌的用户。
import Axios from "axios";
import React, {useState, useEffect, useSelector} from 'react';
import {Route, Redirect} from 'react-router-dom';
function isLogin(){
const result = Axios.get('http://localhost:8081/authentication', {withCredentials: true})
.then(res => {
console.log(res);
})
console.log(result);
}
const PrivateRoute = ({component: Component, ...rest}) => {
return (
<Route {...rest} render={props => (
isLogin() ?
<Component {...props} />
: <Redirect to="/login" />
)} />
);
};
export default PrivateRoute;
看起来(正如预期的那样)只有“console.log(result)”执行了挂起的promise,但在最终结果中,我试图将一些逻辑编码到从后端给出的响应中(true或false),然后这些逻辑应该发送到privaterout组件,以确定是否应该将用户发送回登录,等等。。
我知道这是因为axios.get的异步特性导致了我的问题,但我尝试了几种不同的方法:
使isLogin函数异步,然后等待axios请求
在PrivateRoute返回中创建另一个异步函数,使用wait。
似乎无论我在这里尝试什么,都没有正确地等待axios.get的结果,因此没有给出不想要的结果。。如果您有任何建议,甚至是正确的方向,我都将不胜感激。
非常感谢。
我已经提出了处理这种情况的要点。
你需要两个州。
您将拥有一个对用户进行身份验证的函数,但在进行身份验证时还需要加载状态。
所以你会有这样的东西
return (
<Route
{...rest}
render={props => (
!isLoading
?
(
isAuthenticated
?
<Component {...props} />
:
<Redirect to="/login" />
)
:
<Loading />
)}
/>
)
你会有一个函数来设置这些状态
useEffect(() => {
setIsLoading(true)
isLogin()
.then(() => {
setIsAuthenticated(true)
})
.catch(() => {
setIsAuthenticated(false)
})
.then(() => {
setIsLoading(false)
})
}, [])
正如@Emile Bergeron在评论(参考)中所说,我将在私有路由组件中添加一个状态,该状态将存储用户是否经过身份验证。这将在组件(私有路由)首次挂载时检查。
作为一个代码,以您的代码为基础,它看起来像这样:
import Axios from "axios";
import React, {useState, useEffect, useSelector} from 'react';
import {Route, Redirect} from 'react-router-dom';
const PrivateRoute = ({component: Component, ...rest}) => {
// State
const [authenticated, setAuthentication] = useState(null);
const [loadingComplete, setLoadingComplete] = useState(false);
// Login function
useEffect(
() => {
// ComponentDidMount
// Declare Function (you can also declare it outside the useEffect,
// if you want to run it also if another prop changes for instance.
// But it will be overwritten on every rerender;
// To prevent this you could use useCallback hook)
const isLogin = async () => {
try {
const result = await Axios.get('http://localhost:8081/authentication', {withCredentials: true});
// Store the result, e.g. ID, token, ...
setAuthentication(result);
} catch (e) {
// Something failed
console.log(e);
}
setLoadingComplete(true);
}
// run login function
isLogin();
},
[]
);
if(loadingComplete){
return (
<Route {...rest} render={props => (
!!authenticated ?
<Component {...props} />
: <Redirect to="/login" />
)} />
);
}else{
return ( <div> Loading... </div>);
}
};
export default PrivateRoute;
编辑:当然,您还需要加载过程的状态,因此重定向不会在读取用户之前击中您。
问题内容: 我正在尝试编写一个JS代码,如果给定的数字已经存在于数据库中,它将取消“ btn_submit”按钮.onclick事件。我使用AJAX向数据库查询给定的编号,并确定是否应将数据发送到将上传问题的.php站点。为了确定这一点,我需要numOfRows变量的值,但是因为我在AJAX中将其设置为0,所以validation()函数将在我的AJAX查询完成之前完成,这将导致始终表示给定数字不
问题内容: 在我的程序中,我从另一个API模块调用了我的函数: 模块代码: 执行立即返回,但是,并因此包含请求对象和请求体- 样,不需要响应体。 我做错了什么?怎么修?正确的用法是什么,或仅与此处提到的Promise一起正确使用:为什么await对于节点请求模块不起作用?以下文章提到了可能的方法:在Node.js中掌握Async Await 。 问题答案: 您需要使用模块,而不是模块或。 对返回p
下面的函数在for循环中调用几个异步函数。它解析不同的CSV文件来构建单个JavaScript对象。我想在for循环完成后返回对象。它在执行异步任务时立即返回空对象。有道理,但是我尝试了各种Promise/异步 /await组合,希望在for循环完成后运行一些东西。我显然不明白发生了什么。对于这样的事情,有更好的模式吗?还是我想错了? 这是我用来调用函数的代码,希望用CSV数据填充我的“retCo
我试图在我的Android应用程序中使用AdMob奖励广告。为了包括它在引用的应用程序,我需要等待奖励的视频加载后,用户点击按钮。我在下面的整个代码中都在尝试它,但我得到了错误: IllegalStateException:必须在主UI线程上调用showAd。 当点击臀部时: 重写了侦听器: 使用mRewardedVideoad.isLoaded()函数也会触发同样的问题。
但这一个也不起作用。正确的答案是加入线程并删除2个睡眠: 我的问题是:为什么我的答案都不能被接受?我的实验室领导问,但他不能给我一个答案。在家里编写了测试代码,它似乎工作得很好。提前感谢您的帮助!
我有一个成功登录网站并执行查询的脚本: 我想做的是在另一个网站Trello上做类似的事情。以下是脚本: 但是,result变量会显示一个页面,就好像用户没有登录一样,所以我假设会话没有正确保存。我怎样才能解决这个问题?