ImmutableJS FieldArray loses focus ONLY when value = initialValue
See original GitHub issueI am using FieldArrays. I have other fields not in FieldArrays that pull initialValues asynchronously but do not face this issue.
Redux Form Options: TouchOnBlur: False (Does not change outcome either way) Reinitialize: True
Ex.
Initial Value: 123 (Pulled asynchronously from backend)
Click into field, type 4, 4 gets placed in input field, then you lose focus. Upon clicking in again and typing, you are fine. However, if you get the value back to it’s initial state (i.e. 123, either by backspacing or by deleting the contents of the input and retyping 123), you lose focus again.
This is not the same as #1094, I have already made my render fields stateless, they are outside of my class entirely and do not use arrow functions. This issue only happens when the input matches the initialValue.
Edit 1: The same thing happens when clearing the input. If I backspace all the way to where the input is empty, I lose focus there also.
Edit 2: Here is a minimal example using initial values that are not even asynchronous, yet the problem still happens.
import React, {Component} from 'react';
import Immutable from 'immutable';
import { Field, FieldArray, reduxForm } from 'redux-form/immutable';
import { connect } from 'react-redux';
import {fromJS} from 'immutable';
function renderInputField({ input, label, type, colWidth, meta: { touched, error } }){
return(
<div>
<input {...input} type={type} placeholder={label} className="job-input form-control"/>
<span id="helpBlock" className="help-block">{touched && <span>{error}</span>}</span>
</div>
);
}
class JobHistory extends Component {
renderJobs({fields}){
return(
<div>
<ul id="jobs">
{fields.map((job, index) => {
return (
<li
className="row"
key={index}>
{/* Company */}
<Field
name={`${job}.company`}
type="text"
component={renderInputField}
label="Company"
/>
{/* Role */}
<Field
name={`${job}.title`}
type="text"
component={renderInputField}
label="Role"
/>
<a className="delete"
onClick={() => fields.remove(index)}>
<i className="fa fa-times" aria-hidden="true"></i>
</a>
</li>
);
})}
</ul>
{/* Add New Job */}
<button
className="btn btn-default btn-margin"
type="button"
onClick={() => fields.push(Immutable.Map())}
>Add Job</button>
</div>
);
}
render() {
const {handleSubmit} = this.props;
return (
<div className="container">
<form>
<FieldArray name="jobs" component={this.renderJobs.bind(this)}/>
{/* Submit Button */}
<button
type="button"
className="btn btn-primary btn-margin"
onClick={handleSubmit(values => {
const jobs = [];
values.get('jobs').forEach((job, index) => {
const jobInfo = {
company: job.get('company') || '',
title: job.get('title') || '',
};
jobs[index] = jobInfo;
});
console.log("Calling onSave with: ", jobs);
})}>
Save
</button>
</form>
</div>
);
}
}
function mapStateToProps (state, ownProps) {
const jobs = [];
jobs[0] = fromJS({
company: 'Company1',
title: 'Title1'
});
jobs[1] = fromJS({
company: 'Company1',
title: 'Title1'
});
return {
initialValues: {
jobs
}
};
}
const componentWithForm = reduxForm({
form: 'jobForm'
})(JobHistory);
export default connect(
mapStateToProps,
)(componentWithForm);
Issue Analytics
- State:
- Created 7 years ago
- Comments:7 (1 by maintainers)
Top GitHub Comments
There’s your problem. This is creating a new function every time it’s rendered, which is forcing a re-render of the field array, which is losing your focus. You need to do:
…in your constructor, and then…
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.