Search code examples
javascriptreactjsreact-reduxreact-redux-form

Action won't dispatch with Redux-Form with or without connect


I'm learning react and redux, which by themselves are fine but I've run into a hurdle when it comes to redux-form.

I have the following form:

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import { updateAuthToken } from '../actions/index';

class FormAuthUpdate extends Component {
  render() {
    const { handleSubmit } = this.props;

    return(
      <form onSubmit={handleSubmit} className="form-inline">
        <div className="form-group">
          <label htmlFor="authToken">New Auth Token </label>
          <Field component="input" type="text" name="authToken" className="form-control" />
        </div>
        <button className="btn btn-primary" type="submit">Set</button>
      </form>
    );
  };
}

FormAuthUpdate = reduxForm({ form: 'AuthUpdateForm', onSubmit: updateAuthToken })(FormAuthUpdate);
export default connect( undefined, { updateAuthToken })(FormAuthUpdate);

With the following action:

export const UPDATE_AUTH_TOKEN = "UPDATE_AUTH_TOKEN";

export function updateAuthToken(props) {
  const test = {
    type: UPDATE_AUTH_TOKEN,
    payload: props.authToken
  }

  console.log("action: " + JSON.stringify(test));

  return test;
}

And relevant reducer:

import { UPDATE_AUTH_TOKEN } from '../actions/index';

const INITIAL_STATE = { authToken: "" };

export default function(state = INITIAL_STATE, action) {
  console.log("reducer: " + JSON.stringify(action.type));
  switch(action.type) {
    case UPDATE_AUTH_TOKEN:
      console.log("switch");
      return { ...state, authToken: action.payload.authToken };
    default:
      return state;
  }
}

With the logs, I've been able to determine that the form successfully submits, the updateAuthToken action creator is called, but the action is never dispatched. I've tried this with connect, without connect, with explicitly defined matchDispatchToProps, and still no dispatch. What am I missing?


Solution

  • I've figured it out! The issue was the implementation of the mapDispatchToProps method on connect.

    Here's the updated component:

    import React, { Component } from 'react';
    import { reduxForm, Field } from 'redux-form';
    import { connect } from 'react-redux';
    import { updateAuthToken } from '../actions/index';
    
    class FormAuthUpdate extends Component {
      render() {
        const { handleSubmit, dispatch } = this.props;
        return(
          <form onSubmit={handleSubmit} className="form-inline">
            <div className="form-group">
              <label htmlFor="authToken">New Auth Token </label>
              <Field component="input" type="text" name="authToken" className="form-control" />
            </div>
            <button className="btn btn-primary" type="submit">Set</button>
          </form>
        );
      };
    }
    
    FormAuthUpdate = reduxForm({ form: 'AuthUpdateForm', onSubmit: updateAuthToken })(FormAuthUpdate);
    export default connect( undefined, { onSubmit: updateAuthToken })(FormAuthUpdate);
    

    Updated action creator:

    export const UPDATE_AUTH_TOKEN = "UPDATE_AUTH_TOKEN";
    
    export function updateAuthToken(props) {
      return {
        type: UPDATE_AUTH_TOKEN,
        payload: props.authToken
      }
    }
    

    And the "updated" reducer:

    import { UPDATE_AUTH_TOKEN } from '../actions/index';
    
    const INITIAL_STATE = { authToken: "" };
    
    export default function(state = INITIAL_STATE, action) {
      switch(action.type) {
        case UPDATE_AUTH_TOKEN:
          return { ...state, authToken: action.payload };
        default:
          return state;
      }
    }
    

    As you can see, not much has changed beyond removing a bunch of the logging code. The meat of the solution is on the last line of the component. Instead of binding the updateAuthToken function to dispatch, I had to bind my form's onSubmit function (a different instance of updateAuthToken) to the action creator. This caused the form to submit, dispatch action, and all around successfully complete. I hope this helps anyone working with redux-form!