Обещание возврата из улова с Axios и final-form

Я вхожу в службу api из клиента React с Axios. Форма для имени и пароля обрабатывается final-form. Все работает, как ожидалось, кроме тех случаев, когда я хочу вернуть ошибку из функции onSubmit.

Есть два компонента: родительский Login, который обрабатывает вызов API с помощью logIn функции, и вложенный компонент LoginUi, который имеет форму и функцию onSubmit, которая вызывает родительский метод logIn через this.props.logIn():

Вот метод logIn в родительском компоненте Login:

class Login extends Component {
    constructor() {
        super();
        this.logIn = this.logIn.bind(this);
    }

    logIn(credentials) {
        return axios({
            method: 'post',
            url: 'http://0.0.0.0:3000/v1/login/',
            data: {
                name: credentials.name,
                password: credentials.password,
            },
        })
            .then((response) => {
                return response;
            })
            .catch((error) => {
                return error;
            });
    }

    render() {
        return <LoginUi logIn={this.logIn} {...this.props} />;
    }
}

export default Login;

А вот метод onSubmit в дочернем LoginUi компоненте:

class LoginUi extends Component {
    constructor(props) {
        super(props);
        this.onSubmit = this.onSubmit.bind(this);
    }

    onSubmit(credentials) {
        this.props
            .logIn(credentials)
            .then((result) => {
                console.log(result);
            })
            .catch((error) => {
                console.log(error);

                return { [FORM_ERROR]: 'Login Failed' };
            });
    }

    render() {
        return (
            <div className="LoginUi">
                {/* here goes the form with final-form, not included for brevity */}
            </div>
        );
    }
}

export default LoginUi;

{ [FORM_ERROR]: 'Login Failed' } отвечает за изменение состояния формы - обрабатывается final-form-, но не может этого сделать. Если я верну его за пределами catch, он работает:

onSubmit(credentials) {
    this.props
        .logIn(credentials)
        .then((result) => {
            console.log(result);
        })
        .catch((error) => {
            console.log(error);
        });
    return { [FORM_ERROR]: 'Login Failed' };
}

Но, очевидно, это не то, что я хочу, потому что [FORM_ERROR]: 'Login Failed' должен возвращаться только тогда, когда вызов API возвращает ошибку.

Я почти уверен, что здесь проблема с использованием обещаний. Если у кого-то есть идеи, я был бы признателен!

Спасибо!


person Community    schedule 16.03.2019    source источник
comment
Какой вариант использования можно вернуть? почему ты не setState в улове?   -  person its4zahoor    schedule 16.03.2019
comment
как вы используете / звоните onSubmit?   -  person Thomas    schedule 16.03.2019


Ответы (1)


Поскольку вы полагаетесь на обещания, onSubmit должен вернуть обещание. Добавьте return в onSubmit, иначе он вернет undefined, и final-form не сможет узнать, что вызов axios был завершен:

onSubmit(credentials) {
  return this.props
    .logIn(credentials)
    .then((result) => {
      console.log(result);
    })
    .catch((error) => {
      console.log(error);    
      return { [FORM_ERROR]: 'Login Failed' };
    });
}
person abadalyan    schedule 16.03.2019
comment
Обработчик событий, обозначенный on в начале, не должен ничего возвращать. imo OP должен обновлять состояние внутри обратных вызовов, переданных then и catch. - person Thomas; 16.03.2019
comment
@Thomas На основе doc onSubmit может использоваться final-form непосредственно через createForm звонок. В этом случае явные вызовы setState не требуются. Думаю, в этом весь смысл использования final-form. - person abadalyan; 16.03.2019
comment
На самом деле Final Form предоставляет способ возврата ошибок через обратный вызов, а не обещание, если хотите. Третий параметр, передаваемый вашей функции onSubmit, - это функция обратного вызова. github.com/final-form/ - person Erik R.; 18.03.2019