2015-10-02 11 views
7

Mam formularz z wieloma wejściami tekstowymi. Mam je wszystkie skonfigurowane jako kontrolowane wejścia. Podczas wpisywania pojawia się opóźnienie do kilku sekund, aby nowy tekst był wyświetlany w polu. Oto przykład pola:Reagowanie powolne z wieloma kontrolowanymi wejściami tekstowymi

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

nie mogę dowiedzieć się, co powoduje, że jest tak powolny, lub co zrobić, aby to naprawić.

AKTUALIZACJA: Oto komponent, powinien wystarczyć, aby pokazać, co się dzieje.

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

Nie bądź możliwe bez kompletnego przykładu. –

+0

@FelixKling Przepraszam, zaktualizowałem go o więcej kodu – mrberggg

Odpowiedz

0

Oto przykład wzoru wejściowego, Plug in or pattern for dealing with large forms in React?. Najważniejsze jest, aby twoje dane wejściowe były składnikiem, który przekazuje zmiany rodzicowi, ale nie aktualizuje się z rekwizytów, jeśli są one takie same.

+0

Ok, dziękuję Janaka. Myślałem, że to komplikuje zarządzanie państwem, ale myślę, że powinno to przynajmniej zapobiec niepotrzebnym ponownym wydaniom DOM. – mrberggg

8

Miałem podobną sytuację, a moim rozwiązaniem było wyłączenie React Dev Tools. W jakiś sposób wpływały one na pola wejściowe. Problem polega na tym, że nie wystarczy odświeżyć strony, jeśli kliknąłeś kartę React Dev Tools. Wciąż wpływają na twoje dane wejściowe. Musisz otworzyć nową stronę, aby ich zatrzymać. Możesz też całkowicie usunąć je z Chrome, ale nie polecam tego, ponieważ są one przydatne. :)

+1

Dziękuję za to, że ten problem zdarzał się sporadycznie i tak, to były narzędzia programisty ... Muszą zawierać opcję rozłączenia w narzędziach ... – JosephGarrone

+0

To naprawdę pomogło dla mnie, podstawowy problem nadal istnieje i będę musiał to naprawić przez refaktoryzację mojego komponentu i dodanie 'shouldComponentUpdate', ale na razie wszystko jest w porządku. – Rohmer

2

Istnieje wiele możliwych przyczyn takiego stanu rzeczy. I w obliczu podobnego problemu i filtruje główną przyczynę do:

  • dużego państwa, więc zajmuje się kiedyś
  • reagować Dev Tool/zastosowanie nie minified reagują
  • mutowania danych państwowe

Bez względu na przyczynę, znalazłem szybkie rozwiązanie tego problemu. Jeśli chcesz go zapisać do stanu, ale nie używać go do renderowania na żywo. Następnie możesz bezpiecznie zamienić "onChange" na "onBlur". To nie ma oparcia i opóźnienia. Jeśli znasz inny przypadek, w którym to nie zadziała, daj mi znać!

Zmień kod następująco: <label>Event Name</label> <input type="text" placeholder="Title" className="form-control" name="title" value={this.state.event.title} onBlur={this.handleChange} />

+0

powinieneś użyć wartości defaultValue zamiast wartości, dzięki czemu możesz zmienić wartość wejściową, gdy coś wpiszesz. – Frank

+0

Hi @Frank, próbowałem tego i nie działa, gdy chcę użyć formularza do edycji. Podczas gdy dane edycji docierają za pośrednictwem ajax, wartość początkowa jest renderowana. – aks

Powiązane problemy