Using redux-form I'm losing focus after typing the first character
This happens because you're re-defining renderField
as a new component every time you render which means it looks like a new component to React so it'll unmount the original one and re-mounts the new one.
You'll need to hoist it up:
const renderField = ({ input, label, type, meta: { touched, invalid, error } }) => (
<div class={`form-group ${touched && invalid ? 'has-error' : ''}`}>
<label for={label} className="sr-only">{label}</label>
<input {...input} placeholder={label} type={type} className="form-control" />
<div class="text-danger">
{touched ? error: ''}
</div>
</div>
);
class SignIn extends Component {
...
render() {
const { message, handleSubmit, prestine, reset, submitting } = this.props;
return (
<div className="row">
<div className="col-md-4 col-md-offset-4">
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))} className="form-signin">
<h2 className="form-signin-heading">
Please sign in
</h2>
{this.renderAlert()}
<Field name="email" type="text" component={renderField} label="Email Address" />
<Field name="password" type="password" component={renderField} label="Password" />
<button action="submit" className="btn btn-lg btn-primary btn-block">Sign In</button>
</form>
</div>
</div>
);
}
}
...
As @riscarrott mentioned, put renderField
outside of component class .
But I am still losing focus .. And after testing, I concluded the re-rendering is done because of using curried function (return another function, and not return element . directly) .
const const renderField = (InputComponent = 'input') => ({ input, label, type, meta: { touched, invalid, error } }) => (
<div class={`form-group ${touched && invalid ? 'has-error' : ''}`}>
<label for={label} className="sr-only">{label}</label>
<InputComponent {...input} placeholder={label} type={type} className="form-control" />
<div class="text-danger">
{touched ? error: ''}
</div>
</div>
);
Then, if your renderField
is a curried function :
then , don't do :
//.....
<Field name="email" type="text" component={renderField('input')} label="Email Address" />
<Field name="desc" component={renderField('textarea')} label="Email Address" />
But , do the following :
// outside component class
const InputField = renderField('input');
const TextAreaField = renderField('textarea');
// inside component class
<Field name="email" type="text" component={InputField} label="Email Address" />
<Field name="desc" component={TextAreaField} label="Email Address" />