Search code examples
javascriptreactjsreact-reduxredux-form

Actions must be plain objects. Trying to dispatch an actions into a redux-form


I'm trying to execute an async function when a form is submitted with redux-form, but no matter what, the error:

Actions must be plain objects. Use custom middleware for async actions.

Is always fired... here is my config:

createStore:

export const store = createStore(
  rootReducer,
  compose(
    applyMiddleware(thunk),
    window.devToolsExtension ? window.devToolsExtension() : f => f
  )
);

The actions with thunk:

const loginUser = userData => {
  return {
    type: fb_actions.LOGIN,
    payload: userData
  }
};

export const loginFirebase = (email, password) => {
  firebase.auth()
    .signInWithEmailAndPassword(email, password)
    .then(authData => {
      return dispatch => {
        dispatch(loginUser({email: email, password: password}))
      }
    })
};

The component:

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

import logo from '../static/logo-horizontal-black.svg';
import '../styles/Login.scss';

import renderLoginField from '../helpers/renderLoginField';

class Login extends Component {

  constructor() {
    super();
    this.onFormSubmit = this.onFormSubmit.bind(this);
  }

  onFormSubmit(fields) {
    const { login } = this.props;
    login(fields.email, fields.password);
  };


  render() {
    const {handleSubmit} = this.props;
    return (
      <div className='row'>
        <div className='col-xs-12 col-sm-6 col-md-4 col-md-offset-4 col-md-offset-3'>
          <section className='panel panel-default panel-login'>
            <div className='panel-heading'>
              <img src={logo} role='presentation' alt='cc-logo' className='img-responsive cc-logo' />
            </div>

            <div className='panel-body'>
              <form onSubmit={handleSubmit(this.onFormSubmit)}>
                <Field icon='mail' type='email' component={renderLoginField} name='email' />
                <Field icon='password' type='password' component={renderLoginField} name='password' />
                <button type='submit' className='btn btn-primary login-btn'>Login</button>
              </form>
            </div>
          </section>
        </div>
      </div>
    );
  }
};

Login = reduxForm({ form: 'loginForm' })(Login);

export default Login;

And the container:

import { connect } from 'react-redux';
import Login from '../components/Login';
import { loginFirebase } from '../actions/firebaseActions';

const mapStateToProps = (state, ownProps) => {
  return {
    authData: state.auth
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    login: (email, password) => dispatch(loginFirebase(email, password))
  }
}

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

Any idea about this?


Solution

  • I guess the action has to be chained as below,

    export const loginFirebase = (email, password) => dispatch =>
      firebase.auth()
        .signInWithEmailAndPassword(email, password)
        .then( authData => dispatch(loginUser({ email: email, password: password})));