Skip to content

Instantly share code, notes, and snippets.

@erikras
Created November 14, 2016 22:19
Show Gist options
  • Save erikras/43a60a4adade000254b3f284339d7548 to your computer and use it in GitHub Desktop.
Save erikras/43a60a4adade000254b3f284339d7548 to your computer and use it in GitHub Desktop.
Example showing how to use a formValueSelector on an individual array item
/**
The following can replace the file in the Field Arrays example
(https://github.com/erikras/redux-form/tree/master/examples/fieldArrays) to demonstrate this functionality.
**/
import React from 'react'
import { connect } from 'react-redux'
import { Field, FieldArray, reduxForm, formValueSelector } from 'redux-form'
import validate from './validate'
const selector = formValueSelector('fieldArrays')
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} type={type} placeholder={label}/>
{touched && error && <span>{error}</span>}
</div>
</div>
)
let Member = ({ member, index, fields, hasLastName }) =>
<li key={index}>
<button
type="button"
title="Remove Member"
onClick={() => fields.remove(index)}/>
<h4>Member #{index + 1}</h4>
<Field
name={`${member}.firstName`}
type="text"
component={renderField}
label="First Name"/>
<Field
name={`${member}.lastName`}
type="text"
component={renderField}
label="Last Name"/>
{hasLastName && <div>HAS LAST NAME</div>}
<FieldArray name={`${member}.hobbies`} component={renderHobbies}/>
</li>
Member = connect(
(state, props) => ({
hasLastName: !!selector(state, `${props.member}.lastName`)
})
)(Member)
const renderMembers = ({ fields, meta: { touched, error } }) => (
<ul>
<li>
<button type="button" onClick={() => fields.push({})}>Add Member</button>
{touched && error && <span>{error}</span>}
</li>
{fields.map((member, index) =>
<Member member={member} fields={fields} index={index} key={index}/>)}
</ul>
)
const renderHobbies = ({ fields, meta: { error } }) => (
<ul>
<li>
<button type="button" onClick={() => fields.push()}>Add Hobby</button>
</li>
{fields.map((hobby, index) =>
<li key={index}>
<button
type="button"
title="Remove Hobby"
onClick={() => fields.remove(index)}/>
<Field
name={hobby}
type="text"
component={renderField}
label={`Hobby #${index + 1}`}/>
</li>
)}
{error && <li className="error">{error}</li>}
</ul>
)
const FieldArraysForm = (props) => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<Field name="clubName" type="text" component={renderField} label="Club Name"/>
<FieldArray name="members" component={renderMembers}/>
<div>
<button type="submit" disabled={submitting}>Submit</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values
</button>
</div>
</form>
)
}
export default reduxForm({
form: 'fieldArrays', // a unique identifier for this form
validate
})(FieldArraysForm)
@doptster
Copy link

doptster commented Nov 1, 2018

thank you so much! The code is improving the performance of page for not re-rendering that much.

@jose2007kj
Copy link

thanks this helped me fix my form issues, on which i have been stuck for few days

@gauravjainjpr
Copy link

@erikras,
I have a FieldArray , where I need to do some calculation like when I fill in 2 text boxes , it should validate 2 values for numbers and calculate substraction and populate the result in third text box. Can you please let me know how can we do that and give any pointers/link on the same. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment