超过最大更新深度。无限重定向以及如何更好地安排我的路由

时间:2019-05-30 06:04:57

标签: reactjs react-router

首先,我是React的新手,所以请原谅我的基本问题。我的App组件包含我的React Router路由,并且如果未找到授权用户,但想重定向到登录页面,但出现错误“超过最大更新深度”。

我(认为我)了解到,react陷入了尝试重定向到/ login的无限循环中,但实际上并没有想到解决该问题/重组的更简洁方法。

最初,我的解决方法是调用redirectToLogin(),该方法将设置state.redirectToLogin,以便在重定向时不会再次尝试。在执行此操作的同时,我在其他地方阅读了一些评论,指出render函数中的设置状态是一个很大的禁止。

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 :(得分:0)

我认为问题出在这里

{
    !this.state.authenticated && this.state.redirectToLogin ?
    <Redirect to="/login" /> : null
}

如果页面成功重定向到“ / login”,则此组件App呈现正确吗?然后componentDidMount()将再次求出相同的结果,并且重定向将在无限循环中再次触发。

由于this.state.authenticated是否为true,您仍将处于同一App组件,因此在重定向之前,您需要检查是否已经在“ / login”。

componentDidMount() {
    // 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 });
  }