我的问题很简单,至少看起来如此。我的redux存储中有一个状态,该状态保存用户是否已登录的状态。一切正常,但是当用户刷新页面时,在经过身份验证的状态异步获取其数据的瞬间,渲染运行并且状态未定义。
由于状态未定义,我的重定向到/ login会运行,因此刷新会将我踢出应用程序并返回登录,然后登录查看我是否已经登录并将我带到主页。 / p>
有关如何解决此问题的任何想法:
{
!this.props.authenticated && (
<Switch>
<Route path="/login" component={LoginForm} />
<Route path="/register" component={RegisterForm} />
<Route path="" render={props => {
return <Redirect to="/login" />
}}
/>
</Switch>
)
}
因此,当this.props.authenticated在短时间内为false时,它将命中登录重定向。但是,过了几毫秒,this.props.authenticated为true,并且由于用户已经登录,因此将重定向到本地路由。
有什么想法吗?
答案 0 :(得分:1)
理想情况下,您不会立即渲染路由,而是要等到身份验证请求得到解决并且状态为清除状态。
类似这样的东西:
class App extends React.Component {
constructor( props ) {
super( props );
this.state = {
// You could just check if authenticated is null,
// but I think having an extra state makes is more clear
isLoading: true,
authenticated: null,
};
this.checkAuthentication();
}
checkAuthentication() {
// Some async stuff checking against server
// I’ll simulate an async call with this setTimeout
setTimeout(
() => this.setState( {
authenticated: Boolean( Math.round( Math.random() ) ),
isLoading: false,
} ),
1000
);
}
render() {
// Render a loading screen when we don't have a clear state yet
if ( this.state.isLoading ) {
return <div>loading</div>;
}
// Otherwise it is safe to render our routes
return (
<div>
routes,<br />
random authenticated:
<strong>
{ this.state.authenticated.toString() }
</strong>
</div>
);
}
}
ReactDOM.render( (
<App />
), document.querySelector( 'main' ) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<main></main>
答案 1 :(得分:0)
好的,lumio通过setTimeout帮助我走上了正确的轨道,所以我改用async / await解决了这个问题:
class App extends Component {
state = {
error: "",
isLoading: true,
}
async componentDidMount() {
let token = localStorage.getItem('jwtToken');
if (token) {
setAuthToken(token);
await this.props.isAuthenticatedAction(true);
} else {
await this.props.isAuthenticatedAction(false);
}
this.setState({
isLoading: false,
});
}
handleLogout = (evt) => {
evt.preventDefault();
localStorage.removeItem('jwtToken');
window.location.reload();
}
render() {
if (this.state.isLoading) {
return <div></div>;
} else {
// return my regular content
}
答案 2 :(得分:0)
您可以将react-router-dom用于身份验证工作流程。
@RequestMapping('/service/subDirectoryOfService')
public String subDirectoyOfService(@FormParam String params){
JSONObject json = new JSONObject(params);
String base64 = json.getString("attachedFile");
System.out.println("base64 of file: "+ base64);
return "{\"res\":\"success\"}"
}
引用链接https://reacttraining.com/react-router/web/example/auth-workflow
答案 3 :(得分:0)
首先,当用户尝试登录时,您将在身份验证后收到令牌作为响应。现在您必须使用
将令牌存储在localStorage中if(user.token){
localStorage.setItem('user', JSON.stringify(user));
}
表明当您在本地存储中有令牌时,请先登录,否则退出。
如果您要登录后进入主页,请尝试设置状态以重定向到主页。
this.setState({redirectToReferrer: true});
现在返回重定向到所需页面
if (this.state.redirectToReferrer){
return (<Redirect to={'/home'}/>)
}
login.js
import React from 'react';
import axios from 'axios';
import {Redirect} from 'react-router-dom';
export default class Login extends React.Component{
constructor(props){
super(props);
this.state = {
email : '' ,
password : '',
redirectToReferrer : false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event){
this.setState({
[event.target.name] : event.target.value
});
}
handleSubmit(event){
event.preventDefault();
const user = {
email : this.state.email,
password : this.state.password
};
if(this.state.email && this.state.password)
{
axios.post(`{Api}/login`,user)
.then((response) =>
{
let userresponse = response;
console.log(userresponse.data);
if(userresponse.token){
sessionStorage.setItem('data',JSON.stringify(userresponse));
this.setState({redirectToReferrer: true});
}
},this)
.catch((error) => alert(error))
}
}
render(){
if (this.state.redirectToReferrer){
return (<Redirect to={'/user'}/>)
}
if (sessionStorage.getItem('data')){
return (<Redirect to={'/user'}/>)
}
return(
<div>
<form ref="formdemo" onSubmit={this.handleSubmit}>
<label>
Username:
<input type="email" name="email" onChange={this.handleChange} placeholder="Enter Your EmailID" required/></label><br/>
<label>
Password :
<input type="password" name="password" onChange={this.handleChange} placeholder="Enter Your Password" required/></label><br/>
<input type="submit"/>
</form>
</div>
)
}
}