如何将redux-form的onSubmit与redux-api-middleware集成?

时间:2016-08-03 15:54:39

标签: reactjs redux redux-form

我正在使用redux-formredux-api-middleware编写React / Redux应用程序,而我在将redux-form的onSubmit函数与RSAA生命周期集成时遇到了问题。

redux-form文档说onSubmit处理程序should return是一个承诺。在对承诺调用resolve之前,表单的submitting道具将为true

但是,在此应用中,我的API调用目前不使用promises(例如,通过fetch)。我通过调度[CALL_API] RSAA操作和reducing redux-api-middleware's response actions.

来进行API调用

问题代码

class MyReduxFormContainer extends Component {
  render() {
    return (
      <MyReduxForm submit={this.props.submit} />
    )
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    submit: function(values, dispatch) {
      dispatch({
        [CALL_API]: {
          method: 'PATCH',
          types: [
            {
              type: 'REQUEST',
              endpoint: '...',
              body: JSON.stringify(values)
            },
            'SUCCESS',
            'FAILURE'
          ]
        }
      });
      // Problem: redux-api-middleware-style API calls normally don't leverage promises.
      // Out of the box, this library doesn't offer a promise to return.
    }
  }
};

export default connect(
  // ...
  mapDispatchToProps
)(MyReduxFormContainer)

可能的解决方案

我可以通过payload RSAA回调传递承诺,然后可以在API响应后解析/拒绝承诺,但这似乎违反了“的规则动作创建者不应该引起副作用。“授予redux-api-middleware似乎会改变这个规则。

理论上我可以在fetch处理程序中使用onSubmit,而不是使用redux-api-middleware,但这不仅仅是让我的API的让步在整个应用程序中交互不一致,它也有可能重复我已经烘焙过的任何API中间件活动,例如设置默认标题,去降低/降低有效载荷等等。

有没有人有使用redux-form和redux-api-middleware的经验?

如果它只是redux-api-middleware,我希望在减少submitting动作类型时通过改变表单的状态来简单地更改表单的ACTION_TYPE_[REQUEST|SUCCESS|FAILURE]道具。但是从reducer直接修改表单的状态似乎是非标准的并且可能存在风险。 redux-form实现的示例似乎强调redux-form状态应该是透明的/只是间接操作。

任何想法/指示都将不胜感激!

相关GitHub问题

终极版-API的中间件:

Redux的形式:

2 个答案:

答案 0 :(得分:3)

最近我发现很优雅和通用的方式结合起来。 Here is article with explanation

export const formToApiAdapter = (dispatch, actionCreator, formatErrors) => (
  (...args) => (
    new Promise((resolve, reject) => (
      dispatch(actionCreator(...args)).then(
        (response) => {
          if (response.error) {
            return reject(formatErrors(response));
          }
          return resolve(response);
        }
      )
    ))
  )
);

答案 1 :(得分:1)

由于缺乏更好的解决方案,我目前正在减少形式的dispatch({[CALL_API]})处理程序中将我的submit调用包含在Promise中。

class MyReduxFormContainer extends Component {
  render() {
    return (
      <MyReduxForm submit={this.props.submit} />
    )
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    submit: function(values, dispatch) {

      // Solution: Wrap the [CALL_API] dispatch in a Promise
      return new Promise((resolve, reject) => {

        dispatch({
          [CALL_API]: {
            method: 'PATCH',
            types: [
              {
                type: 'MY_PATCH_REQUEST'
                endpoint: '...',
                body: JSON.stringify(values)
              },
              {
                type: 'MY_PATCH_SUCCESS',
                payload: function (action, state, res) {

                  // Solution: resolve() the promise in the SUCCESS payload callback
                  // Changes `submitting` prop of MyReduxForm
                  resolve();

                }
              },
              {
                type: 'MY_PATCH_FAILURE',
                payload: function (action, state, res) {

                  // Solution: reject() the promise in the FAILURE payload callback
                  // Changes `submitting` prop of MyReduxForm
                  reject();

                }
              }
            ]
          }
        });

      });

    }
  }
};

export default connect(
  // ...
  mapDispatchToProps
)(MyReduxFormContainer)

最终,我对此代码架构非常不满意,此时我认为标准fetch用法优于redux-api-middleware

API响应之后的触发效果足够标准作为一个问题,应该有比这种回调嵌套更优雅的解决方案,例如,使用承诺链。