使用 Redux 表单处理 AJAX 错误

Handling AJAX Errors with Redux Form

我是 React/Redux 的新手,所以我正在使用 Redux Form 构建一个简单的博客应用程序来帮助我学习。现在我不清楚在我的操作中将数据从表单提交到 api 时如何处理 ajax 错误。主要问题是我正在使用 Redux Form 的 onSubmitSuccess 配置 属性,它似乎总是被调用,即使发生错误也是如此。我真的不清楚是什么触发了 onSubmitSuccess 或 onSubmitFail。我的 onSubmitFail 函数永远不会执行,但我的 onSubmitSuccess 函数总是执行,无论是否发生错误。

我在 redux-form 文档中读到了 SubmissionError,但它说它的目的是 "to distinguish promise rejection because of validation errors from promise rejection because of AJAX I/O"。所以,这听起来与我需要的相反。

我正在使用 redux-promise 作为 Redux 的中间件,如果这有什么不同的话。

这是我的代码。我故意在我的服务器 api 中抛出错误以在我的 createPost 操作中生成错误:

带有我的 redux 形式的容器

PostsNew = reduxForm({
  validate,
  form: 'PostsNewForm',
  onSubmit(values, dispatch, props) {
    // calling my createPost action when the form is submitted.
    // should I catch the error here?
    // if so, what would I do to stop onSubmitSuccess from executing?
    props.createPost(values)
  }
  onSubmitSuccess(result, dispatch, props) {
    // this is always called, even when an exeption occurs in createPost()
  },
  onSubmitFail(errors, dispatch) {
    // this function is never called
  }
})(PostsNew)

onSubmit 调用的操作

export async function createPost(values) {
  try {
    const response = await axios.post('/api/posts', values)
    return {
      type: CREATE_POST,
      payload: response
    }
  } catch (err) {
    // what would I do here that would trigger onSubmitFail(),
    // or stop onSubmitSuccess() from executing?
  }
}

要处理异步操作,您应该使用 redux-thunk, redux-saga 或其他可以实现 运行 异步代码的中间件。

在你的例子中,redux-form 不知道表单提交是否成功,因为你没有从 onSubmit 函数返回 Promise。

在您的情况下,可以在不使用 redux-promise 或任何其他异步处理库的情况下实现此目的:

PostsNew = reduxForm({
  validate,
  form: 'PostsNewForm',
  onSubmit(values, dispatch, props) {
    // as axios returns a Promise, we are good here
    return axios.post('/api/posts', values);
  }
  onSubmitSuccess(result, dispatch, props) {
    // if request was succeeded(axios will resolve Promise), that function will be called
    // and we can dispatch success action
    dispatch({
      type: CREATE_POST,
      payload: response
    })
  },
  onSubmitFail(errors, dispatch) {
    // if request was failed(axios will reject Promise), we will reach that function
    // and could dispatch failure action
    dispatch({
      type: CREATE_POST_FAILURE,
      payload: errors
    })
  }
})(PostsNew)