Как запустить onSubmit = {} только после обновления реквизита? - PullRequest
1 голос
/ 22 апреля 2019

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

const mapStateToProps = state => {
  return {
    authError: state.auth.authError  // I want this to update before the action.
  };
};

Если я сохраняю authError console.log в обработчике onSutmit, я получаю старый authError. При втором запуске я получаю обновленную ошибку authError.

  handleSubmit = e => {
    e.preventDefault();
    console.log("error exists?", this.props.authError);
    this.props.signIn(this.state); //dispatches a login action
    this.handleHideLogin(); // hides the form after action is dispatched
};

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

Я пытался использовать setTimeout (), и он технически работает, но я хочу знать, есть ли более "правильный" способ сделать это.

handleSubmit = e => {
    e.preventDefault();
    this.props.signIn(this.state);

     setTimeout(() => {
       if (this.props.authError) {
         console.log("returns error =>", this.props.authError);
       } else {
         console.log("no error =>", this.props.authError);
         this.handleHideLogin();
       }
     }, 500);
  };

часть моего компонента для справки

<form onSubmit={!this.props.authError ? this.handleSubmit : null}> 
   //the above onSubmit is different if I use the setTimeout method.
          <div className="modal-login-body">
            <div className="modal-login-input">
              <input
                type="email/text"
                name="email"
                autoComplete="off"
                onChange={this.handleChange}
                required
              />
              <label htmlFor="email" className="label-name">
                <span className="content-name">EMAIL</span>
              </label>
            </div>
            <div className="modal-login-input">
              <input
                type="password"
                name="password"
                autoComplete="off"
                onChange={this.handleChange}
                required
              />
              <label htmlFor="password" className="label-name">
                <span className="content-name">PASSWORD</span>
              </label>
            </div>
          </div>
          <div className="my-modal-footer">
            <p className="login-failed-msg">
              {this.props.authError ? this.props.authError : null}
            </p>
            <button type="submit" className="complete-login-button">
              LOGIN
            </button>
            <a href="CHANGE" className="forgot-password">
              <u>Forgot your password?</u>
            </a>
          </div>
        </form>

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

Я предполагаю, что this.props.signIn является асинхронной функцией. И, таким образом, this.props.authError обновляется асинхронно, и поэтому, если вы установите время ожидания, оно будет работать в некоторых случаях (когда вы получите ответ короче 5 секунд).

Один из способов решить эту проблему - использовать then и catch без обновления состояния формы

handleSubmit = e => {
    e.preventDefault();
    this.props.signIn(this.state).then(resp => {
        this.setState({userIsValid: true, failure: null})
        this.onUpdate(userIsValid);
    })
    .catch(err => {
       this.setState({userIsValid: false, failure: "Failed to login"})
    });
}

и используйте if-else, чтобы определить, показывать ли форму или показывать ваш веб-сайт

class App extends React.Component {
  render() {
    if (this.state.isValidUser) {
      return <Main />
    } else {
      return <LoginForm onUpdate={(isValid) => {this.setState({isValidUser: isValid})} />
    }
  }
}

Другими словами, компонент LoginForm хранит имя пользователя, пароль, сбой (сообщение об ошибке, почему вход не выполнен) и isValidUser (чтобы определить, успешен ли вход в систему). Приложение имеет состояние, чтобы определить, что показать, веб-сайт или компонент входа в систему. Используя onUpdate, который передается в качестве реквизита компоненту входа в систему, мы можем обновить состояние приложения и показать веб-сайт, если вход выполнен успешно.

Надеюсь, это поможет.

0 голосов
/ 22 апреля 2019

Я решил эту проблему путем условного рендеринга всего компонента.Я использовал перенаправление из response-router-dom, чтобы просто не отображать элемент, если я вошел в систему.

Если я вошел в систему, мне все равно не нужно отображать форму входа.

   if (this.props.loggedOut) {
      <form onSubmit={this.handleSubmit}>
        //...
      </form>
    } else {
      return <Redirect to="/" />;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...