2015-10-02 53 views
7

我有一個具有多個文本輸入的表單。我把它們全部設置爲控制輸入。打字時,新文字在字段中顯示時會有幾秒的延遲。這裏是一個示例字段:反應速度慢,具有多個受控文本輸入

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

我們不能或者沒有一個完整的例子。 –

+0

@FelixKling對不起,我用更多的代碼更新了 – mrberggg

回答

0

這裏是一個輸入模式的例子,Plug in or pattern for dealing with large forms in React?。最重要的是將你的輸入作爲一個組件,將更改傳遞給父項,但如果它們相同,則不會從道具更新。

+0

好的,謝謝Janaka。我認爲這會使管理狀態複雜化,但我想它至少應該可以防止不必要的DOM重組。 – mrberggg

8

我有類似的情況,我的解決方案是禁用React開發工具。他們以某種方式影響輸入字段。問題是如果您點擊了React Dev Tools選項卡,刷新頁面是不夠的。他們仍然在影響你的投入。你必須打開新頁面來阻止它們。您也可以將它們從Chrome完全刪除,但我不建議這樣做,因爲它們很有用。 :)

+1

謝謝你,我有這個問題間歇性地發生,是的,這是開發工具...他們需要包括一個斷開選項的工具.... – JosephGarrone

+0

這真的幫助我的事情,底層問題仍然存在我必須通過重構我的組件並添加'shouldComponentUpdate'來修復它,但現在沒關係。 – Rohmer

2

發生這種情況有很多可能的原因。我面臨着類似的問題,並過濾主要事業:

  • 大國,所以它有時佔用
  • 陣營開發工具/非縮小的反應
  • 變異狀態數據

的使用無論是什麼原因,我找到了一個快速解決方案。如果您只是想將其存儲到狀態,但不能將其用於實時渲染。然後,您可以安全地將'onChange'替換爲'onBlur'。這沒有dealay和滯後。如果您知道任何其他情況下無法正常工作,請告訴我!

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

+0

您應該使用defaultValue而不是value,這樣您可以在輸入內容時更改輸入值。 – Frank

+0

嗨@Frank,我試過了,它不起作用,以防我想使用窗體進行編輯。編輯數據通過ajax到達時,初始值被渲染。 – aks