Search code examples
reactjsreduxreact-reduxmaterial-uiredux-form

Handle form props of a redux-form stylised with material-ui


I'm trying to create a login form that makes a API call who returns a token. I'm new with react and redux so to do that I followed this tutorial.

The login form is a redux-form. Here is the code :

login.js

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

const form = reduxForm({  
  form: 'login'
});

class Login extends Component {  
  handleFormSubmit(formProps) {
    this.props.loginUser(formProps);
  }

  renderAlert() {
    if(this.props.errorMessage) {
      return (
        <div>
          <span><strong>Error!</strong> {this.props.errorMessage}</span>
        </div>
      );
    }
  }

  render() {
    const { handleSubmit } = this.props;

    return (
      <div>
        <form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
        {this.renderAlert()}
        {/* {this.renderAlert.bind(this)} */}
          <div>
            <label>Username</label>
            <Field name="username" component="input" type="text" />
          </div>
          <div>
            <label>Password</label>
            <Field name="password" component="input" type="password" />
          </div>
          <button type="submit">Login</button>
        </form>
      </div>
    );
  }
}

function mapStateToProps(state) {  
  return {
    errorMessage: state.auth.error,
    message: state.auth.message
  };
}

export default connect(mapStateToProps, { loginUser })(form(Login));

When the form is submitted, the props ({username, password}) are passed to HandleFormSubmit and then to loginUser function who is a redux action created to call the login API. That worked perfectly but now I'm trying to integrate Material Ui to stylised the fields of the form.

// input basic version
<Field name="username" component="input" type="text" />
// material-ui version 
<Field name="username" component={TextField} type="text" />

With this change the props username and password are not passed to handleFormSubmit function so I can't realize a correct API call to login the user. So I need your help to fix this issue.


Solution

  • You need to introduce a translation layer from the props redux-form provides to the material-ui component. This is covered in the redux-form docs here.

    For a TextField this would look like this:

    const renderTextField = ({
      input,
      label,
      meta: { touched, error },
      ...custom
    }) => (
      <TextField
        hintText={label}
        floatingLabelText={label}
        errorText={touched && error}
        {...input}
        {...custom}
      />
    )
    

    Then you pass this as the component to the Field:

    <Field name="username" component={renderTextField} />
    

    There is also a library that already has most of the wrappers you could need that you can just import and use just as you did called redux-form-material-ui.