Превышена максимальная глубина обновления.Бесконечные перенаправления и как лучше структурировать мою маршрутизацию - PullRequest
0 голосов
/ 30 мая 2019

Во-первых, я очень новичок в React, так что простите мой самый основной вопрос. У меня есть компонент App, содержащий мои маршруты 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;

Я надеюсь, что есть простое исправление, которое я упускаю, но я открыт для реструктуризации, если есть более чистый способ.

1 Ответ

0 голосов
/ 01 июня 2019

Я думаю, что проблема здесь

{
    !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 });
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...