question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ImmutableJS FieldArray loses focus ONLY when value = initialValue

See original GitHub issue

I 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)}>
                  &nbsp;
                  <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:closed
  • Created 7 years ago
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

10reactions
erikrascommented, Feb 10, 2017
<FieldArray name="jobs" component={this.renderJobs.bind(this)}/>
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^

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:

this.renderJobs = this.renderJobs.bind(this)

…in your constructor, and then…

<FieldArray name="jobs" component={this.renderJobs}/>
0reactions
lock[bot]commented, Jun 1, 2018

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

In React ES6, why does the input field lose focus after typing a ...
When your onChange event fires, the callback calls setState with the new title value, which gets passed to your text field as a...
Read more >
Field - Redux Form
A function to call when the form field loses focus. It expects to either receive the React SyntheticEvent or the current value of...
Read more >
erikras/redux-form - Gitter
(I think I saw it while working with redux-form and its FieldArray?) ... for example my initial value for address is null but...
Read more >
Final Form – Announcement - erikras.com
It's only for React? ... “Why does my input lose focus on first keypress? ... since the values were provided to the form...
Read more >
update only one document id in subcollection in firestore in ...
Can only update a mounted or mounting component · React update only one object of the state · ImmutableJS - Update only one...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found