Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export mapStateToProps and Redux Form?

I'm using Redux Form (ver. 6) for a log in page. What I would like to do is when the user fills out the form and clicks submit, grab the text from my state so that I can eventually dispatch an action with that email and password. However, I'm having trouble with exporting this component while using both connect from react-redux and Redux Form.

Using react-redux, connect wants to be exported like so when mapping state to props:

export default connect(mapStateToProps)(LogInForm)

However, Redux Form wants it's export set up like this:

export default reduxForm({
  form: 'LogInForm',
  validate,
})(LogInForm);

Is there a way to combine these two? I'd tried something like:

const reduxFormConfig = reduxForm({
  form: 'LogInForm',
  validate,
});

export default connect(mapStateToProps)(ReduxFormConfig)(LogInForm)

but it did not work.

Or Perhaps that's a better approach to handling this? Here is the full code from within my component:

import React from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import InputField from '../InputField';
import { validateLogInSignUp as validate } from '../../utils/validateForms.js';

const LogInForm = (props) => {
  const {
    handleSubmit,
    pristine,
    submitting,
  } = props;

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <Field
          name="email"
          type="email"
          component={InputField}
          label="email"
        />
        <Field
          name="password"
          type="password"
          component={InputField}
          label="password"
        />
        <div>
          <button type="submit" disabled={submitting}>Submit</button>
        </div>
      </form>
    </div>
  );
};

const mapStateToProps = state => {
  return {
    loginInput: state.form,
  };
};

// export default connect(mapStateToProps)(LogInForm)

// export default reduxForm({
//  form: 'LogInForm',
//  validate,
// })(LogInForm);

Any and all help is much appreciated. Thanks!

like image 306
hidace Avatar asked Oct 26 '16 12:10

hidace


2 Answers

There still a way to combine these two in reduxForm v6:

reduxForm({
  form: 'LogInForm',
  validate,
})(LogInForm);

export default connect(mapStateToProps)(LogInForm)

Here is how:

import React, { Component } from 'react';
import { connect } from 'react-redux

class LogInForm extends Component {
    ...
}

function mapStateToProps(state) {
    return { ... }
}

function mapDispatchToProps(dispatch) {
    return { ... }
}

// First decorate your component with reduxForm
LogInForm = reduxForm({
  form: 'LogInForm',
  validate,
})(LogInForm);

// Then connect the whole with the redux store
export default connect(mapStateToProps, maDispatchToProps)(LogInForm)
like image 72
doncredas Avatar answered Oct 06 '22 19:10

doncredas


There are multiple threads with same issue. I recently posted my take with my solution here but with a few variations.

  1. I used a class based component than a function based. I have found guides to specifically implement that way and explaining that the connect method of react-redux make it a Higher Order Component and as such it is best used with a class instance.

  2. As mentioned by @doncredas, reduxForm and react-redux's connect method should be implemented separately, however, my implementation is as follows:

    function mapStateToProps(state) {
        return { form: state.form };
    }
    
    Signin = connect(mapStateToProps, actions)(Signin);
    Signin = reduxForm({
     form: 'signin'
    })(Signin);
    export default Signin;
    

[Added later] Another variation can be:

const form = reduxForm({ form: 'signin' });
export default connect(mapStateToProps, actions)(form(Signin));
like image 23
JaysQubeXon Avatar answered Oct 06 '22 20:10

JaysQubeXon