[英]How do I fetch data from API before render method called? (react, passport, express)
我正在尝试验证用户是否已通过护照进行身份验证,然后才允许他们访问特定路线。 为此,我需要访问我的 API,它将返回我的用户的身份验证状态。 但是,我希望在路由渲染之前进行调用,以使路由保持受保护状态。 这是我目前的尝试:
import React, { Component } from 'react';
import { Route, Redirect } from 'react-router-dom';
class ProtectedRoute extends Component {
constructor(){
super()
this.fetchAuthState().then(result => console.log('result',result))
this.state = {
isAuth: false,
error: null
}
}
async fetchAuthState() {
try {
const response = await fetch('http://localhost:3001/logincheck', {
headers: {
'content-type': 'application/json',
accept: 'application/json',
},
});
return await response.json();
} catch (error) {
console.error(error);
this.setState({ error });
}
};
render() {
console.log('client check', this.state.isAuth)
const { component: Component, ...props } = this.props
return (
<Route
{...props}
render={props => (
this.state.isAuth ?
<Component {...props} /> :
<Redirect to='/login' />
)}
/>
)
}
}
export default ProtectedRoute;
这是服务器端代码:
app.get('/logincheck', (req, res) =>{
res.send(req.isAuthenticated())
})
我认为由于反应生命周期,应该在构造函数中调用 fetch,然后将其存储在 state 中。 但是,当我尝试直接或在临时变量中存储结果时,获取结果显示未定义。 我已经检查了护照文档中是否有任何客户端形式的 isAuthenticated(),但它似乎只适用于服务器端。 我正在考虑实施 jwt 令牌系统,以查看这是否是维护身份验证状态的更好方法,但认为使用 api 路由来检查会更容易。 我是 web 开发的新手,因此非常感谢任何建议/批评!
您可以添加一些加载屏幕,直到身份验证响应到达。
开始加载 state 并在组件安装时进行获取
class ProtectedRoute extends Component {
constructor(){
super()
this.state = {
isAuth: false,
error: null,
loading:true // default loading will be true
}
}
componentDidMount(){
this.fetchAuthState().then(result => this.setState({loading:false})) // after fetch end set loading false
}
....
render() {
console.log('client check', this.state.isAuth)
const { component: Component, ...props } = this.props
return (
{this.state.loading ? <LoadingComponent/> :<Route
{...props}
render={props => (
this.state.isAuth ?
<Component {...props} /> :
<Redirect to='/login' />
)}
/>}
)
}
}
您可以通过添加一个额外的 state 变量(类似于loading
)然后在 API 返回响应时切换它来完成此操作。 但我会稍微重构您的代码,使其看起来像这样:
import React, { Component } from 'react';
import { Route, Redirect } from 'react-router-dom';
class ProtectedRoute extends Component {
constructor(){
super()
this.state = {
loading: true,
isAuth: false,
error: null
}
}
componentDidMount(){
fetch('http://localhost:3001/logincheck', {
headers: {
'content-type': 'application/json',
accept: 'application/json',
},
})
.then(res => res.json())
.then(json => {
this.setState({isAuth: json.isAuth, loading: false})
})
.catch(e => console.log(e))
}
render() {
console.log('client check', this.state.isAuth)
const { component: Component, ...props } = this.props;
const {loading, isAuth} = this.state;
return (
<Route
{...props}
render={() => {
return loading ?
<div>Loading...</div>
:
isAuth ?
this.props.children
:
<Redirect to='/login' />
}} />
)
}
}
export default ProtectedRoute;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.