Search code examples
reactjsreduxredux-formredux-thunk

Separate API calls using dispatch from redux-forms "onSubmit"


I integrated redux-form as the docs suggest and everything works fine. As the next step i wanted to add async API-calls to my application and combine them with the forms created by redux-form.

As usual, i want to seperate my ui components from application logic. The redux way of doing this is dispatching actions in the components and doing the necessary logic inside the reducers. When you need async operations inside your actions/actionCreators one uses redux-thunk or probably other libraries like redux-saga.

Let's assume i want to use redux-thunk to use async api calls inside my actionCreators for updating my application state. The question now is, how would anyone combine this with the logic that redux-form gives us in the onSubmit function? This function assumes that you return a promise to handle the states of the form and i cannot find a way to combine this with the usual way of using actions.

Doesn't redux-form provide a reduxy way of handling the submit function using actions?

Feel free to ask anything if something is unclear or you need some code to get a clearer picture of what i want to achive. Thanks!


Solution

  • Redux-form allows you to pass in a submit handler property, which you can use elsewhere.

    A possible approach.

    Your parent component:

    class FormHandler extends Component {
      constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
      handleSubmit(data) {
        return this.props.asyncAction(data).then(() => {
          throw new SubmissionError({ user: 'Username already taken.', _error: 'Form submission failed' });
        }
      }
      render() {
        return <MyForm onSubmit={this.handleSubmit} />
      }
    }
    
    export default connect(mapStateToProps, { asyncAction })(FormHandler);
    

    You can connect your parent component, like you would normally do without redux-form, and handleSubmit can be an action which is connected to your store.

    You can find more about submit validation on Redux form official documentation.

    Your redux-form MyForm:

    class MyForm extends Component {
      render() {
        const { error, handleSubmit, onSubmit, submitting } = this.props;
    
        return (
          <form onSubmit={handleSubmit(onSubmit)}>
              ... fields ...
              <button type="submit" disabled={submitting}>Create</button>
          </form>
        );
      }
    }
    
    MyForm.PropTypes = {
      onSubmit: PropTypes.func.isRequired
    };
    
    export default reduxForm({
      form: 'myForm',
    })(MyForm);