Search code examples
javascriptreactjsredux-form

How to render the form in React?


I'm trying to make a form in React, I'm very new to it, and I'm combining two tutorials that I watched. However, when I try to make a form it doesn't show up.

formField.js:

export default [
{ label: 'Title', name: 'contactTitle' },
{ label: 'First Name', name: 'contactName' },
{ label: 'Last Name', name: 'contactLastName' },
{ label: 'Email', name: 'contactEmail' },
{ label: 'Telephone', name: 'contactTelephone' },
{ label: 'Address', name: 'contactAddress' },
];

Then I have a ContactField.js where I'm making a single field of the form:

import React from 'react';

export default ({input, label, meta: {error, touched}}) => {
  return (
    <div>
      <label>{label}</label>
      <input {...input} style={{marginBottom: '5px'}} />
      <div className="red-text" style={{marginBottom: '20px'}}>
        {touched && error}
      </div>
    </div>
  )
}

And in the end I have the component ContactNew.js. Only my h2 and button are being rendered on the page, the whole form is missing:

import _ from 'lodash';
import React, { Component } from 'react';
import { Field, Form, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import ContactField from './ContactField';
import { createContact } from '../../actions';
import formField from './formField';
import validateEmails from '../../utils/validateEmail';

class ContactNew extends Component {
    renderFields() {
        return _.map(formField, ({ label, name }) => {
            <Field
                key={name}
                component={ContactField}
                type="text"
                label={label}
                name={name}
            />;
        });
    }
    onSubmit(values) {
        this.props.createContact(values, () => {
            this.props.history.push('/');
        });
    }

    render() {
        const { handleSubmit } = this.props;
        return (
            <div>
                <h3>Add new contact:</h3>
                <Form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
                    {this.renderFields()}
                    <button className="waves-effect waves-light btn blue darken-1" type="submit">Save</button>
                </Form>
            </div>
        );
    }
}

function validate(values) {
    const errors = {};

    errors.contactEmail = validateEmails(values.contactEmail || '');

    _.each(formField, ({ name }) => {
        if (!values[name]) {
            errors[name] = 'You must provide a value';
        }
    });
    return errors;
}

export default reduxForm({
    validate,
    form: 'contactForm',
    destroyOnUnmount: false
})(connect(null, { createContact })(ContactNew));

In my actions I have:

export function createContact(values, callback) {
  const request = axios.post('/api/client', values)
    .then(() => callback());


  return {
    type: CREATE_CONTACT,
    payload: request
  }
}

I don't know if there is only one small mistake that is not rendering my form, or all of it is wrong. I don't get any errors in the console.


Solution

  • You have a syntax error on renderFields. You are not returning created component from map and you have an extra ;(semicolon) at the end of FormField. Please take a look at how to use map at lodash docs

    Should be like this

    renderFields() {
      return _.map(formField, ({ label, name }) => (
        <Field
          key={name}
          component={ContactField}
          type="text"
          label={label}
          name={name}
        />
      ));
    }