Во-первых, я очень новичок в React, поэтому простите мой очень простой вопрос. У меня есть компонент приложения, содержащий маршруты React Router, и я хочу перенаправить на страницу входа, если авторизованный пользователь не найден, но я получаю сообщение об ошибке «Превышена максимальная глубина обновления».
Я (думаю, я) понимаю, что реакция попала в бесконечный цикл попыток перенаправления на /login, но не могу придумать более чистый способ решения проблемы/реструктуризации.
Первоначально мое исправление состояло в том, чтобы вызвать redirectToLogin(), который установил state.redirectToLogin, чтобы при перенаправлении он не пытался снова. Пока это работало, я прочитал несколько комментариев в другом месте, что указанное состояние настройки в функции рендеринга — это большое нет-нет.
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom';
import { Loading } from './components/loading/Loading';
import { Navbar } from './components/navbar/Navbar';
import AuthService from './services/auth-service';
import { Users } from './components/users/Users';
import { UsersCreate } from './components/users/users-create/UsersCreate';
import { Login } from './components/auth/Login';
import './App.scss';
import './styles/variables.scss';
type State = {
loading: boolean,
authenticated: boolean,
redirectToLogin: boolean
}
class App extends Component<{}, State> {
authService: AuthService;
constructor(props: any) {
super(props);
this.authService = new AuthService();
this.state = {
loading: false,
authenticated: false,
redirectToLogin: false
};
// this.redirectToLogin = this.redirectToLogin.bind(this);
// Intercept 401 responses and redirect to login
AuthService.registerUnauthenticatedInterceptor();
}
componentDidMount() {
// Check if user is authenticated
if (AuthService.getUser()) {
this.setState({
authenticated: true
});
} else {
this.setState({
redirectToLogin: true
})
}
this.setState<any>({ loading: false });
}
// redirectToLogin() {
// this.setState({
// redirectToLogin: false
// });
// return <Redirect to = "/login" />
// }
render() {
if (this.state.loading) {
return <Loading />
}
if (!this.state.loading) {
return (
<div className = "App">
<Router>
{
this.state.authenticated ?
<Navbar /> : null
}
{
!this.state.authenticated && this.state.redirectToLogin ?
<Redirect to = "/login" /> : null
}
<Route exact path = "/login" render = {() => <Login />} />
<div className = "component-page">
<div className = "container-fluid">
<Route exact path = "/users" render = {() => <Users />} />
<Route exact path = "/users/create" render = {() => <UsersCreate />} />
</div>
</div>
</Router>
</div>
)
}
}
}
export default App;
Я надеюсь, что есть простое исправление, которое мне не хватает, но я открыт для реструктуризации, если есть более чистый способ.
я думаю проблема здесь
{
!this.state.authenticated && this.state.redirectToLogin ?
<Redirect to = "/login" /> : null
}
Если страница успешно перенаправляется на «/login», то это же самое компонентное приложение отображается правильно? Затем componentDidUpdate() снова вернет тот же результат, и перенаправление снова сработает в бесконечном цикле.
Поскольку независимо от того, является ли this.state.authenticated истинным или нет, вы все равно будете находиться в том же компоненте приложения, поэтому перед перенаправлением вам необходимо проверить, находитесь ли вы уже в «/login» или нет.
componentDidUpdate() {
// Check if user is authenticated
if (AuthService.getUser()) {
this.setState({
authenticated: true
});
} else {
if (this.props.location.pathname != '/login') {
this.setState({
redirectToLogin: true
})
}
}
this.setState<any>({ loading: false });
}
Оказывается, componentDidMount не вызывается снова при повторном рендеринге, но вызывается componentDidUpdate. Поэтому я использовал этот метод, чтобы проверить, произошло ли перенаправление, и предотвратить его повторение. Если вы обновитесь до componentDidUpdate(), я приму ваш ответ. Спасибо за вашу помощь!
Хорошо, спасибо за ваш отзыв. Изменил ответ, как вы предложили.
«Превышена максимальная глубина обновления» — эта проблема возникает при возникновении бесконечного цикла. Вам необходимо предоставить другие компоненты, чтобы понять, откуда возникла проблема.