Search code examples
reactjsreact-reduxreact-thunk

Uncaught TypeError: dispatch(...).then is not a function


Container component

import { connect } from 'react-redux';
import { signUpUser } from '../actions/userActions';

import Register from '../components/register';

function mapStateToProps(state) {
    return { 
      user: state.user
    };
}

const mapDispatchToProps = (dispatch, ownProps) => {
    return {

    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Register);

Register form

import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router-dom';
import { reduxForm, Field, SubmissionError } from 'redux-form';
import { signUpUser } from '../actions/userActions';

//Client side validation
function validate(values) {
  var errors = {};
  var hasErrors = false;


  return hasErrors && errors;
}

//For any field errors upon submission (i.e. not instant check)
const validateAndSignUpUser = (values, dispatch) => {
    //console.log(values);
    return dispatch(signUpUser(values))
      .then((response) => {
      console.log(response);
    });
};


class SignUpForm extends Component {

  render() {
    const { handleSubmit } = this.props;
    return (
      <div className="col-md-6 col-md-offset-3">
        <h2>Register</h2>
        <form onSubmit={ handleSubmit(validateAndSignUpUser) }>
          <div className ='form-group'>
              <label htmlFor="firstname">Name</label>
              <Field name="firstname" type="text" component= "input"/>
          </div>
          <div className ='form-group'>
              <label htmlFor="username">Username</label>
              <Field name="username" type="text" component= "input"/>
          </div>
          <div className ='form-group'>
              <label htmlFor="password">Password</label>
              <Field name="password" type="text" component= "input"/>
          </div>
          <div className="form-group">
              <button className="btn btn-primary">Register</button>
              <Link to="/" className="btn btn-error"> Cancel </Link>
          </div>
      </form>
     </div>
    )
  }
}

export default reduxForm({
  form: 'SignUpForm', // a unique identifier for this form
  validate
})(SignUpForm)

Actions

import axios from 'axios';

export function signUpUser(user) {
  console.log(user);

  const url = `https://jsonplaceholder.typicode.com/posts`
  const request = axios.get(url); 

  return {
    type: 'Register_User',
    payload: request
  };
}

When I submit this form I am getting following error. This app uses thunk, setup form reducer in combined reducer. Where am I going wrong? I am new to redux-form and thunk

Uncaught TypeError: dispatch(...).then is not a function

Solution

  • The return value of dispatch is the return value of the inner function and in your case an object and not a promise. (https://github.com/reduxjs/redux-thunk#composition) You have to return axios.get(...) (which basically returns a Promise) directly in the action in order to call then() on the return value of dispatch like you did in your example.

    What I would suggest doing is to not put the request for the signup in a separate action because it's easier to handle the request right in the submit function of redux form. Otherwise it could be difficult to handle responses from the server with validation messages. I also think that you won't need to reuse the action in any other place, right? If you need to change something in the state after the registration, you can simply create another action like "signedUpUser" and pass some data to it.