Подтвердить что ты не робот

Реакция медленная с несколькими управляемыми текстовыми вводами

У меня есть форма с несколькими текстовыми вводами. У меня все они настроены как управляемые входы. При наборе текста для отображения нового текста в поле появляется задержка в несколько секунд. Вот пример поля:

<label>Event Name</label>
<input type="text" 
       placeholder="Title"
       className="form-control"
       name="title"
       value={this.state.event.title}
       onChange={this.handleChange} />

Я не могу понять, почему это так медленно или что делать, чтобы исправить это.

ОБНОВЛЕНО: здесь компонента должно быть достаточно, чтобы показать, что происходит.

let CreateEventForm = React.createClass({
  submit: function () {},
  handleChange: function(e){
    let value = e.target.value;
    let name = e.target.name;
    if(value === 'true'){
      value = true;
    }
    if(value === 'false'){
      value = false;
    }
    // If true/false toggle old
    let oldState = this.state.event[name];
    if(typeof oldState === 'boolean'){
      value = !oldState;
    }
    // If is array
    if(name.indexOf('[]') > -1){
      name = name.replace('[]', '');
      oldState = this.state.event[name];
      var pos = oldState.indexOf(value);
      if(pos > -1){
        oldState.splice(pos, 1);
      } else {
        oldState.push(value);
      }
      value = oldState;
    }
    let event = this.state.event;
    event[name] = value;
    this.setState({event: event});
    console.log(this.state.event);
  },
  getClasses(field, additionalClasses = []) {
    // If a string is passed for additional class, make array
    if(!Array.isArray(additionalClasses)){
      additionalClasses = [additionalClasses];
    }
    let useDefaultColumns = additionalClasses.filter(function(className){
        return className.indexOf('col-') > -1;
      }).length === 0;
    let hasError = function(){
      let fields = Array.isArray(field) ? field : [field];
      return fields.filter(function(field){
          return !this.props.isValid(field);
        }.bind(this)).length > 0;
    }.bind(this)();
    return classnames({
      'col-sm-4': useDefaultColumns,
      'form-group': true,
      'has-error': hasError
    }, additionalClasses);
  },
  render: function () {
    return (
      <form ref="eventForm" onSubmit={this.submit}>
        <SavedModal isOpen={this.state.saved} reset={this.resetForm} style={this.state.modals.styles} />
        <h3>Info</h3>

        <div className="row">
          <div className={this.getClasses('title')}>
            <label>Event Name</label>
            <input type="text" placeholder="Title"
                   className="form-control"
                   name="title"
                   value={this.state.event.title}
                   onChange={this.handleChange} />
            {this.renderHelpText(this.props.getValidationMessages('title'))}
          </div>
        </div>
        <div className="row">
          <div className={this.getClasses('type')}>
            <label>Event Type</label>
            <select name="type"
                    className="form-control"
                    value={this.state.event.type}
                    onChange={this.handleChange}
                    onBlur={this.props.handleValidation('type')}>
              <option value="">Select Event Type&hellip;</option>
              {this.state.calendarTypes.map(function (type, key) {
                return <option value={type.name} key={key}>{type.name}</option>
              })}
            </select>
            {this.renderHelpText(this.props.getValidationMessages('type'))}
          </div>
        </div>

        <h3>Duration</h3>

        <div className="row">
          <div className="form-group col-sm-2">
            <input type="checkbox" name="allDay" checked={this.state.event.allDay} onChange={this.handleChange}/> All Day
          </div>
        </div>
        <div className="row">
          <div className="form-group col-sm-2">
            <input type="checkbox" name="repeats" checked={this.state.event.repeats} onChange={this.handleChange}/> Repeats&hellip;
          </div>
          <br/><br/>
        </div>

        <h3>Location</h3>
        <div className="row">
          <div className={this.getClasses('location')}>
            <select name="location"
                    className="form-control"
                    value={this.state.event.location}
                    onBlur={this.props.handleValidation('location')}
                    onChange={this.handleChange}>
              <option value="">Select a Location&hellip;</option>
              {this.state.locations.map(function (location, key) {
                return (
                  <option value={location.name} key={key}>{location.name}</option>
                );
              })}
            </select>
            {this.renderHelpText(this.props.getValidationMessages('location'))}
          </div>
        </div>

        <h3>Description</h3>
        <div className="row">
          <div className={this.getClasses('description')}>
            <label>Write a description:</label>
            <textarea className="form-control"
                      name="description"
                      value={this.state.event.description}
                      onChange={this.handleChange}
                      onBlur={this.props.handleValidation('description')}
                      rows="10"></textarea>
            {this.renderHelpText(this.props.getValidationMessages('description'))}
          </div>
        </div>

        <h3>Event Details</h3>
        <div className="row">
          <div className={this.getClasses('fee')}>
            <label>Fee:</label>
            <input type="text"
                   className="form-control"
                   name="fee"
                   value={this.state.event.fee}
                   onChange={this.handleChange}
                   onBlur={this.props.handleValidation('fee')}/>
            {this.renderHelpText(this.props.getValidationMessages('fee'))}
          </div>
        </div>

        <div className="row">
          <div className="col-sm-12">
            <button className="btn btn-primary" type="submit">
              Create Event
            </button>
          </div>
        </div>

      </form>
    );
  }
});
4b9b3361

Ответ 1

У меня была аналогичная ситуация, и моим решением было отключить React Dev Tools. Они каким-то образом влияли на поля ввода. Проблема заключается в том, что недостаточно обновить страницу, если вы нажали вкладку "Реагировать инструменты". Они все еще влияют на ваши входы. Вы должны открыть новую страницу, чтобы остановить их. Вы также можете полностью удалить их из Chrome, но я не рекомендую это делать, потому что они полезны.:)

Ответ 2

Есть много возможных причин для этого. Я столкнулся с подобной проблемой и отфильтровал основную причину:

  • Большое государство, так что это займет время
  • React Dev Tool/Использование неунифицированного реагирования
  • Мутирующие данные о состоянии

Какой бы ни была причина, я нашел быстрое решение для этого. Если вы просто хотите сохранить его в состоянии, но не использовать для визуализации в реальном времени. Тогда вы можете смело заменить onChange на onBlur. Это не имеет сделки и задержки. Если вы знаете какой-либо другой случай, когда это не сработает, дайте мне знать!

Измените код следующим образом:

<label>Event Name</label>
<input 
   type="text" 
   placeholder="Title"
   className="form-control"
   name="title"
   value={this.state.event.title}
   onBlur={this.handleChange} />

Ответ 4

У меня было промежуточное программное обеспечение излишнего логгера, чтобы создать эту задержку ввода. Итак, попробуйте отключить это тоже.

Ответ 5

Моя проблема заключалась в том, что мой объект состояния был сложным и, таким образом, вызывал проблемы рендеринга. Мое решение состояло в том, чтобы управлять состоянием заметок в моем компоненте, а затем при размытии обновлять состояние контейнера.

const { data, onEdit } = props;
const { containerNotes } = data;

const [notes, setNotes] = useState('');

useEffect(
  () => {
    setNotes(containerNotes);
  },
  [containerNotes],
);

const onChangeNotes = () => ({ target: { value } }) => {
  setNotes(value);
};

const onBlurNotes = (prop) => ({ target: { value } }) => {
  const newData = update(data, {
    [prop]: { $set:  value },
  });
  onEdit(newData);
};

return (
  <input 
     type="text" 
     placeholder="Title"
     name="title"
     value={notes}
     onChange={onChangeNotes()}
     onBlur={onBlurNotes('containerNotes')}
 />
)