Search code examples
reactjsredux-formreact-redux-form

Redux Form v6 - Generating dynamic form with unique keys loses focus on entering value


hope someone know's the issue. I have an Array like:

let fields = [
    { name: 'email', type: 'email', placeholder: 'Email', component: FeedbackInput },
    { name: 'password', type: 'password', placeholder: 'Passwort', component: FeedbackInput }
];

And i want to render it within my redux form via:

<form onSubmit={ handleSubmit(this.props.startAnimation.bind(this, 'animatedBtnConfig')) }>
 <fieldset>
  { fields.map(field => <Field key={_.uniqueId('field_')}  { ...field } component={ FeedbackInput } />) }
 </fieldset>
 <fieldset className="center">
  <AnimatedButtonRedux />
 </fieldset>
</form>

So the problem is that the form is initial valid and i can enter only 1 character. Then it looses the focus from the input field and have to click it again.

Same Problem when i try it with "FieldArray":

<FieldArray name="authData" component={ DynamicFields } fields={ fields } />

Dynamic Fields Component:

export default props => {
  console.log("Dynamic Fields: ", props);
  return (
    <div>
      { props.fields.map(field => <Field key={_.uniqueId('field_')} { ...field }  />) }
    </div>
  );
};

Instead, when i trying it this way:

<Field { ...fields[0] } />
<Field { ...fields[1] } />
<Field { ...fields[2] } />

It work's well.

I can't see any difference in the devtool's when i look at the DOM. Why does redux form behave's this way? I can't figure it out. I would really appreciate it, when someone could give me the crucial tipp to solve this issue!


Solution

  • That happens because of the unique id that you provide as a key to the Field component like key={_.uniqueId('field_')}

    So what happens is whenever your component is rerendered, react checks for the key to render the DOM, now because your key is uniquely generated each time the component is rendered and map function runs, your Field component is replaced everytime with a new one and hence you see this problem.

    Although you need to set the key and it should be unique through the document but it should remain the same on each render.

    So change the key to

    <fieldset>
      { fields.map((field, index) => <Field key={index}  { ...field } component={ FeedbackInput } />) }
     </fieldset>