ReactJS: превышена максимальная глубина обновления (приватный маршрут, логин, дом) - PullRequest
0 голосов
/ 05 марта 2019

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

Превышена максимальная глубина обновления.Это может произойти, когда компонент повторно вызывает setState внутри componentWillUpdate или componentDidUpdate.React ограничивает количество вложенных обновлений для предотвращения бесконечных циклов.

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

Home

class Home extends Component {
  constructor(props) {
    super(props);
  }
  componentDidMount() {
    this.props.getCurrentProfile();
    console.log(this.props.auth.isAuthenticatedUser);
    // if (!this.props.auth.isAuthenticatedUser) {
    //   this.props.history.push("/");
    // }
  }

  render() {
    const { user } = this.props.auth;
    const { profile, loading } = this.props.profile;

    let homeContent;
    if (profile === null || loading) {
      homeContent = <Spinner />;
    } else {
      if (Object.keys(profile).length > 0) {
        homeContent = <h1>Hi</h1>;
      } else {
        homeContent = (
          <div>
            <p className="lead text-muted">Welcome {user.name}</p>
          </div>
        );
      }
    }
    return (
      <div className="home">
        <div className="container">
          <div className="row">
            <div className="col-md-12">
              <h1 className="display-4">Dashboard</h1>
              {homeContent}
            </div>
          </div>
        </div>
      </div>
    );
  }
}

Home.propTypes = {
  getCurrentProfile: PropTypes.func.isRequired
  // deleteAccount: PropTypes.func.isRequired,
  // auth: PropTypes.object.isRequired
  // profile: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  profile: state.profile,
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { getCurrentProfile }
)(Home);

Логин

class Login extends Component {
  constructor() {
    super();

    this.state = {
      email: "",
      password: "",
      errors: {}
    };

    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }
  componentDidMount() {
    if (this.props.auth.isAuthenticatedUser) {
      this.props.history.push("/home");
    }
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.auth.isAuthenticatedUser) {
      this.props.history.push("/home");
    }

    if (nextProps.errors) {
      this.setState({ errors: nextProps.errors });
    }
  }

  onChange = e => {
    this.setState({ [e.target.name]: e.target.value });
  };

  onSubmit = e => {
    e.preventDefault();
    const userData = {
      email: this.state.email,
      password: this.state.password
    };
    this.props.loginUser(userData);
  };

  render() {
    const { errors } = this.state;
    return (
      <div>
        <div className="row">
          <div className="landing">
            <div className="dark-overlay landing-inner text-light">
              <div className="container">
                <div className="row">
                  <div className="col-md-6">
                    <div className="form-container">
                      <div className="login">
                        <div className="row">
                          <div className="col-md-12 m-auto">
                            <h2 className="heading text-center">Log In</h2>
                            </p>
                            <form onSubmit={this.onSubmit}>
                              <div className="form-group">
                                <input
                                  type="email"
                                  className={classnames(
                                    "form-control form-control-sm",
                                    {
                                      "is-invalid": errors.email
                                    }
                                  )}
                                  placeholder="Email Address"
                                  name="email"
                                  value={this.state.email}
                                  onChange={this.onChange}
                                />
                                {errors.email && (
                                  <div className="invalid-feedback">
                                    {errors.email}
                                  </div>
                                )}
                              </div>
                              <div className="form-group">
                                <input
                                  type="password"
                                  className={classnames(
                                    "form-control form-control-sm",
                                    {
                                      "is-invalid": errors.password
                                    }
                                  )}
                                  placeholder="Password"
                                  name="password"
                                  value={this.state.password}
                                  onChange={this.onChange}
                                />
                                {errors.password && (
                                  <div className="invalid-feedback">
                                    {errors.password}
                                  </div>
                                )}
                              </div>
                              <input
                                type="submit"
                                className="btn btn-info btn-block mt-4"
                              />
                            </form>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

Login.propTypes = {
  loginUser: PropTypes.func.isRequired,
  auth: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth,
  errors: state.errors
});

export default connect(
  mapStateToProps,
  { loginUser }
)(Login);

Частный маршрут

import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";

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

PrivateRoute.propTypes = {
  auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(mapStateToProps)(PrivateRoute);

Редактировать: Вот мои App.js, где я установил PrivateRouter для компонента Home

..
   <Route path="/login" component={Login} />
            <Route path="/register" component={Register} />
            <Switch>
              <PrivateRoute path="/home" component={Home} />
            </Switch>

..

1 Ответ

0 голосов
/ 05 марта 2019

componentWillRecieveProps устарел, так что вы, вероятно, должны найти способ с более обновляемым будущим.https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops

Я думаю, что происходит то, что nextProps.errors всегда верно, и вы неопределенно устанавливаете состояние.Было бы лучше, если бы значение начиналось с undefined, если вы хотите использовать свой подход

По сути, {} - это верное значение, и вы хотите проверить наличие ошибок, а не объект ошибокэто правда.

Учтите это:

let obj = {};

if (obj) {
  console.log("hello")
}

let notObj = undefined;
if (notObj) {
  console.log('world')
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...