具有状态的离子反应重定向导致“超出最大更新深度”错误

时间:2019-12-29 13:53:53

标签: reactjs ionic-framework react-router setstate

我正在开发一个PrivateRoute组件,以在用户未登录的情况下重定向到Login页面。直接访问Login Page时,负载很大。在PrivateRoute组件中,当我在重定向中放置“状态:{from:props.location}”时,会导致错误“超出最大更新深度”。浏览器中的路径确实更改为/ login,但是“登录”页面未加载。

我相信setState导致了循环,但是我找不到它在哪里触发。如果未设置state中的Redirect属性,它将按预期工作。

App.tsx:

<IonRouterOutlet>
   <Route exact path="/login" render={(props) => <Login {...props} />}/>
   <PrivateRoute path="/dashboard" component={Dashboard} />
   <PrivateRoute path="/list/:status" component={List} />
   <PrivateRoute path="/detail/:id" component={Detail} />
   <Route exact path="/" render={() => <Redirect to="/dashboard" />} />
</IonRouterOutlet>

PrivateRoute.tsx:

export const PrivateRoute: FunctionComponent<PrivateRouteProps> = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => {
    console.log("PrivateRoute");

    const currentUser: string | null  =  localStorage.getItem("userId");
    if (!currentUser) {
        return <Redirect to={{ pathname: '/login', state: { from: props.location } }} /> // 
    }
    return <Component {...props} />
  }} />
);

Login.tsx:

import axios from 'axios';
import FormErrors from './../components/formErrors';   

  type Props = {};
  type PropsType = RouteComponentProps<Props>

  type State = {
    error: string,
    loading: boolean,
    form: {
      emailAddress: string,
      password: string
      _csrf: string,
    }
  };

class Login extends Component <PropsType, State> {

  constructor(props: PropsType) {
    super(props);
    this.state = {
      error: "",
      loading: false,
      form: {
        emailAddress: '',
        password: '',
        _csrf: ''
      },
    };
  };

  componentDidMount(this: this) {
    console.log("componentDidMount")
    axios.get('http://localhost:1337/api/grant-csrf-token')
      .then(response => {
        const _csrf = response.data._csrf
        this.setState({
          form: {
            ...this.state.form,
            _csrf: _csrf,
          }})
      }).catch(error => {
        console.log(error);
        this.setState({
          error: "Check the internet connection and reload the page",
        });
      });
  }

  handleInputChange = (event: React.FormEvent<HTMLInputElement>): void => {
    console.log("handleInputChange")
    //Update State
  };

  handleSubmit = (e: FormEvent): void => {
    console.log("handleSubmit")
    // Send Data
  };

  renderError = () => {
    console.log("Error is: " + this.state)
    if (this.state.error !== "") {
      return (
        <FormErrors formErrors={this.state.error} />
      );
    }
    console.log("Error Free")
    return "";
  };

  render() {
    return (
      <>
        <IonHeader>
          <IonToolbar>
            <IonTitle>Login</IonTitle>
          </IonToolbar>
        </IonHeader>
        <IonContent>
          <IonCard>
            <form onSubmit={(e: React.FormEvent) => { this.handleSubmit(e);}}>
              <IonList>
                <IonItem>
                  <IonLabel>Email Address</IonLabel>
                  <IonInput name="emailAddress" type="text" value={this.state.form.emailAddress} onInput={(e: any) => this.handleInputChange(e)}/>
                </IonItem>
                <IonItem>
                  <IonLabel>Password</IonLabel>
                  <IonInput name="password" type="password" value={this.state.form.password} onInput={(e: any) => this.handleInputChange(e)}/>
                </IonItem>
                <IonItem class="hidden">
                  <IonLabel>_csrf</IonLabel>
                  <IonInput name="_csrf" type="text" disabled={true} value={this.state.form._csrf} onInput={(e: any) => this.handleInputChange(e)}/>
                </IonItem>
              </IonList>
              <IonButton expand="block" type="submit">Login</IonButton>
            </form>
          </IonCard>
          <IonCard class="error-card alert-danger text-center align-middle">
            { this.state.error !== "" ? this.renderError() : "" }
          </IonCard>
        </IonContent>
      </>
    );
  };
};

export default withRouter(Login);

Chrome控制台,将/ dashboard重定向路由到Loginenter image description here

0 个答案:

没有答案