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

Во-первых, я очень новичок в 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;

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

«Превышена максимальная глубина обновления» — эта проблема возникает при возникновении бесконечного цикла. Вам необходимо предоставить другие компоненты, чтобы понять, откуда возникла проблема.

Rajesh Bhartia 30.05.2019 08:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
1
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

я думаю проблема здесь

{
    !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(), я приму ваш ответ. Спасибо за вашу помощь!

fire_melo0n 02.06.2019 07:16

Хорошо, спасибо за ваш отзыв. Изменил ответ, как вы предложили.

jimmy5312 02.06.2019 09:22

Другие вопросы по теме