Using a redux form, I lose focus after entering the first character

I use redux-formand check lubrication. After entering the first character in the input element, it loses focus, and I have to click it again to continue entering. He does this only with the first character. Subsequent types of characters remain tricks. Here is my main character in the form example:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import * as actions from '../actions/authActions';

require('../../styles/signin.scss');


class SignIn extends Component {

  handleFormSubmit({ email, password }) {
    this.props.signinUser({ email, password }, this.props.location);
  }

  renderAlert() {
    if (this.props.errorMessage) {
      return (
        <div className="alert alert-danger">
          {this.props.errorMessage}
        </div>
      );
    } else if (this.props.location.query.error) {
      return (
        <div className="alert alert-danger">
          Authorization required!
        </div>
      );
    }
  }

  render() {

    const { message, handleSubmit, prestine, reset, submitting } = this.props;

    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>
    );


    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>
    );
  }
}

function validate(values) {
  const errors = {};

  if (!values.email) {
    errors.email = 'Enter a username';
  }

  if (!values.password) {
    errors.password = 'Enter a password'
  }

  return errors;
}

function mapStateToProps(state) {
  return { errorMessage: state.auth.error }
}

SignIn = reduxForm({
  form: 'signin',
  validate: validate
})(SignIn);

export default connect(mapStateToProps, actions)(SignIn);
+16
source share
4 answers

This is because you redefine it renderFieldas a new component at each rendering, which means that it looks like a new component for Response, so it will disable the original one and mount the new one again.

:

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>
    );
  }
}

...
+28

@riscarrott, renderField .

. , - curried ( , ).

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>
    );

, renderField :

, 😔😔😔😔:

     //.....

     <Field name="email" type="text" component={renderField('input')} label="Email Address" />
     <Field name="desc" component={renderField('textarea')} label="Email Address" />

🙂🙂🙂🙂:

  // 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" />
+2

. , createForms():

export const ConfigureStore = () => {
  const store = createStore(
    combineReducers({

      tasks: Tasks,
      task: Task,
      image: Image,
      admin: Admin,
      pageId: PageID,
      fieldValues: FieldValues,
      formValues: FormValues,

      ...createForms({
        createTask: initialTask,
        editTask: initialEditTask
      })
    }),
    applyMiddleware(thunk, logger)
  );

  return store;
}
Hide result
0

The refactoring of the component based on arrowFunction to the component based on the class worked for me, since the behavior of the InputForm components was strange. Each time the value of each input was changed, they all redrawn, even after dividing each inputType into separate components. There is nothing left but to change the main component to a class one. I suggest that this may be caused by the most redundant form.

0
source

Source: https://habr.com/ru/post/1656620/


All Articles