gpt4 book ai didi

javascript - react - react 路由器 - privateRoute - 无限循环

转载 作者:行者123 更新时间:2023-12-03 01:49:15 24 4
gpt4 key购买 nike

我正在尝试在我的单页应用程序中创建一个简单的身份验证系统。我想为访客禁用除 /login 之外的所有路由。了解用户是否通过身份验证或访客的方法是了解 localStorage 中是否有 access_token

当我启动应用程序时,Main 组件将启动。该组件定义路由并通过检查 localStorage 来了解用户是否经过身份验证。

默认路由 (/) 用于渲染 Home 组件,但是像这样 example react routerHome 组件受 PrivateRoute 对象保护。

PrivateRoute 对象检查用户是否经过身份验证。如果是,则呈现 Home 组件,否则用户将被重定向到 /login 处的 login 组件。

如果成功,Login 组件会将用户重定向到 /,并执行回调以提供 access_token

Main组件定义回调,它将把access_token保存在localStorage中并更改state 用于声明用户已通过身份验证。现在,用户可以访问 Home 组件。

我的问题是,PrivateRoute 系统始终将用户检查为访客,因此它始终重定向到 /login。但是,当 localStorage 中的 access_token 时,Login 组件会重定向到受 PrivateRoute 保护的 Home 尽管有 handleLogin 回调,但这是一个无限循环。

你能找到解决办法吗?

<小时/>

Main.jsx

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Link, Redirect, Route} from "react-router-dom";
import {Login} from "./Login"
import {Home} from "./Home";


class Main extends Component {
constructor(props) {
super(props);

this.handleLogout = this.handleLogout.bind(this);
this.handleLogin = this.handleLogin.bind(this);
this.state = {authed: localStorage.getItem('access_token') !== null};
}

componentDidCatch(error, info) {
}

handleLogout(event) {
event.preventDefault();
localStorage.removeItem('access_token');
this.setState({authed: false});
}

handleLogin(token) {
localStorage.setItem('access_token', token);
this.setState({authed: token !== null});
}

render() {
const PrivateRoute = ({component: Component, ...rest}) => (
<Route {...rest} render={props =>
this.state.authed()
? (<Component {...props} />)
: (<Redirect to="/login"/>)
}
/>
);

const LoginLogout = () => {
return this.state.authed
? (<button onClick={this.handleLogout}>Logout</button>)
: (<Link to="/login">Login</Link>);
};

return (
<BrowserRouter>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<LoginLogout/>
</li>
</ul>

<Route path="/login" component={() => <Login handleLogin={this.handleLogin}/>}/>
<PrivateRoute exact path="/" component={Home}/>

</div>
</BrowserRouter>
);
}
}

if (document.getElementById('main')) {
ReactDOM.render(<Main/>, document.getElementById('main'));
}

Login.jsx

import React, {Component} from 'react';
import {Redirect} from "react-router-dom";

export class Login extends Component {

constructor(props) {
super(props);

this.state = {
email: '',
password: '',
redirect: localStorage.getItem('access_token') !== null,
token: null,
loading: false,
error: null
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

componentWillUnmount() {
this.props.handleLogin(this.state.token);
}

handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;

this.setState({
[name]: value
});
}

handleSubmit(event) {
event.preventDefault();
this.setState({
error: null,
loading: true
});
axios.post('/api/login', {
'client_id': '3',
'email': this.state.email,
'password': this.state.password,
'confirm_password': this.state.password
}).then((response) => {
let token = response.data.access_token;
this.setState({
redirect: true,
token: token,
loading: false
});
}, (error) => {
console.error('error', error.response.data);
this.setState({
error: error.response.data,
loading: false
});
});
}

render() {

if (this.state.redirect)
return (<Redirect to={"/"}/>);

return (
<form onSubmit={this.handleSubmit}>
<label htmlFor="email">Email :</label>
<input type="text" name="email" id="email" value={this.state.email} onChange={this.handleInputChange}
disabled={this.state.loading}/>
<label htmlFor="password">Password :</label>
<input type="password" name="password" id="password" value={this.state.password}
onChange={this.handleInputChange} disabled={this.state.loading}/>
<button type="submit"
disabled={this.state.loading}>{this.state.loading ? "..." : "Se connecter"}</button>
{this.state.error && (
<div>
<p>Erreur : {JSON.stringify(this.state.error)}</p>
</div>
)}
</form>
);
}
}

最佳答案

在您的 handleSubmit 函数中,您需要从 props 调用 handleLogin ,以便在容器组件中正确更新状态。

 handleSubmit(event) {
...

.then((response) => {
let token = response.data.access_token;
this.setState({
redirect: true,
token: token,
loading: false
});
// here, call the handle from props
this.props.handleLogin(token);
}

...

这样,您的 this.state.authed 将具有正确的值

关于javascript - react - react 路由器 - privateRoute - 无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50489452/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com