Artisan Artisan - 1 month ago 15
React JSX Question

Obtaining field's object for displaying validation error message in redux-form

I would like to do sync validation, but I have no ideas how to obtain the field's object

validate.js

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

if (!values.firstName) {
errors.firstName = 'Firstname is required';
} else if (values.firstName.length < 5 || values.firstName.length > 10) {
errors.firstName = 'Firstname must be between 5 - 10';
}
return errors;
}

export default validate;


SimpleReduxForm.js

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { reduxForm, Field } from 'redux-form'
import validate from './validate'

const fields = [ 'firstName', 'lastName', 'age' ]

@reduxForm({
form: 'simpleReduxForm',
fields,
validate
})
export default class SimpleReduxForm extends Component {
render() {
const { handleSubmit, invalid, pristine, submitting } = this.props
const { fields } = this.props
console.log(fields)
return (
<div>
<form onSubmit={ handleSubmit(this.handleFormSubmit) }>

<Field name="firstName" component="input" type="text" />
<Field name="lastName" component="input" type="text" />
<Field name="age" component="input" type="number" />

<input type="submit" value="Submit" disabled={ pristine || invalid || submitting }/>
</form>
</div>
)
}
}


The output of
console.log(fields)
from the source code above as below

enter image description here


It's just an array not object


I have seen sample coding from the documentation as below but I have no ideas how to get mine to work

const { fields: { firstName, lastName } } = this.props

...
{ firstName.touched && firstName.error && <div>{ firstName.error }</div> }


Please advise, thanks

Answer

There is a good example of how to do this on the redux-forms website. The gist is that you should render a component for your Field which will then have access to that input's data. For example, here's one of mine using some twitter-bootstrap error styling.

const renderField = ({ input, label, type, meta: { touched, invalid, error } }) => (
  <div class={`form-group ${touched && invalid ? 'has-error' : ''}`}>
    <label>{label}</label>
    <input {...input} placeholder={label} type={type} className="form-control" />
    <div class="text-danger">
      {touched ? error: ''}
    </div>
  </div>
);

Note that you just need to pull out touched, invalid, etc instead of object.property.touched, etc.

I use this from my Field declaration like so:

<Field name="name" type="text" component={renderField} label="Name" />