How to submit redux-form with material-ui

Asked by At

I am using react-boilerplate + material-ui + redux-form. I have the immutable reducer in place.

My issue is getting the submitted values from the form; I have an onSubmit={} action on the form, but using a type="submit" on a Material-UI button refreshes the whole page and seems very wrong, so I just need some help on the correct way to be able to work with the values of the form.

This is the full code example, feel free to suggest anything that seems a bit wrong.

*Also having some difficulties with the form error message display, but thats probably something much different, but I think error in Textfield only accepts a bool. But I want the firstName and email fields to be required, and email lowercased. *

import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form/immutable';

// Core
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import TextField from '@material-ui/core/TextField';

const validate = values => {
  const errors = {};

  if (!values.get('email')) {
    errors.email = 'Required';
  } else if (
    !/^[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.get('email'))
  ) {
    errors.email = 'Invalid email address';
  }

  return errors;
};

const renderTextField = ({
  input,
  label,
  meta: { touched, error },
  ...custom
}) => (
  <TextField
    placeholder={label}
    helperText={label}
    error={touched && error}
    {...input}
    {...custom}
  />
);

class FormContactAdd extends React.Component {
  handleSubmit = values => {
    console.log('test');
    console.log(values);
  };

  render() {
    const { pristine, submitting } = this.props;

    return (
      <form onSubmit={this.handleSubmit}>
        <Grid container spacing={24}>
          <Grid item xs={12} sm={4}>
            <Field
              fullWidth
              name="firstName"
              component={renderTextField}
              label="First Name"
            />
          </Grid>
          <Grid item xs={12} sm={4}>
            <Field
              fullWidth
              name="lastName"
              component={renderTextField}
              label="Last Name"
            />
          </Grid>

          <Grid item xs={12} sm={6}>
            <Field
              fullWidth
              name="email"
              component={renderTextField}
              label="Email"
            />
          </Grid>


          <Grid item xs={12}>
            <Button
              color="primary"
              size="large"
              variant="contained"
              disabled={pristine || submitting}
            >
              Add Contact
            </Button>
          </Grid>
        </Grid>
      </form>
    );
  }
}

FormContactAdd.propTypes = {
  classes: PropTypes.object,
  handleSubmit: PropTypes.func,
  pristine: PropTypes.bool,
  submitting: PropTypes.bool,
};

export default reduxForm({
  form: 'formContactAdd',
  validate,
})(connect()(withStyles(styles)(FormContactAdd)));

1 Answers

-1
cr kushal On

I think you are doing it in a wrong way.On the form you have called the handleSubmit function directly which is not appropriate in reduxForm. You have 2 approaches.

1.You can do as you are doing but inside of the handleSubmit function you have to accept the event argument and prevent reloading the page.

handleSubmit = e =>{
 e.preventDefault();
//your logic here
}

2.Instead of it you can use the handleSubmit function provided by reduxForm as props and inside the function you can pass your function as callback.

 <form onSubmit={this.porps.handleSubmit(this.handleSubmit)}>

and your button should be

 <button type="submit">

your form and button should be like this

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

    return (
      <form onSubmit={handleSubmit(this.handelSubmit)}>
        <Grid container spacing={24}>
          <Grid item xs={12} sm={4}>
            <Field
              fullWidth
              name="firstName"
              component={renderTextField}
              label="First Name"
            />
          </Grid>
          <Grid item xs={12} sm={4}>
            <Field
              fullWidth
              name="lastName"
              component={renderTextField}
              label="Last Name"
            />
          </Grid>

          <Grid item xs={12} sm={6}>
            <Field
              fullWidth
              name="email"
              component={renderTextField}
              label="Email"
            />
          </Grid>


          <Grid item xs={12}>
            <Button
              type='submit'
              color="primary"
              size="large"
              variant="contained"
              disabled={pristine || submitting}
            >
              Add Contact
            </Button>
          </Grid>
        </Grid>
      </form>
    );
  }